Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 870

Přidáno uživatelem Ondřej Fibich před více než 13 roky(ů)

Nove logy akci, volitelne ukladatelne podle tridy a instance modelu. Moznost filtrovat akce (add, update, delete) zvlast.
Zakomponovani logu do stavajicich controlleru (Vypnuti logu u importu z bank. uctu a telefonnich faktur).
Pro fungovani logu, musi byt zaptut scheduler.

Pri upgreatu databaze se nove testuje verze MySQL, pokud je verze nizsi nez 5.1.0, neni umozneno fungovani systemu. (Partitions pouzite k logovani, jsou dostupne az od teto verze)

Opraven bug v parseru telefonnich faktur, neumoznujici import 0211.
Pridano zobrazeni cenovych polozek s DPH u detailu telefonnich faktur.

Opraveno zobrazeni GPS sourandic u zarizeni, pridana napoveda pro format GPS souradnic.

Trida Table_Form_Item doplnena o moznost uziti argumentu HTML elementu.

Zobrazit rozdíly:

freenetis/branches/testing/application/i18n/cs_CZ/texts.php
'accounting system' => 'Účetní osnova',
'accounts' => 'Účty',
'action' => 'Akce',
'action logs' => 'Logy akcí',
'action logs of object' => 'Logy akcí objektu',
'action logs of user' => 'Logy akcí uživatele',
'activate' => 'Aktivovat',
'activated number has not been changed' => 'Aktivované číslo již nelze změnit',
'activation date' => 'Datum aktivace',
......
'change language' => 'Změnit jazyk',
'change member limit' => 'Změnit limit člena',
'change password' => 'Změnit heslo',
'changed values' => 'Změněné hodnoty',
'change voicemail password' => 'Změnit heslo hlasové schránky',
'channel' => 'Kanál',
'check again' => 'Znovu zkontrolovat',
......
'database name' => 'Název databáze',
'database password' => 'Heslo k databázi',
'database username' => 'Uživatelské jméno k databázi',
'database variables' => 'Databázové proměnné',
'date' => 'Datum',
'date and time' => 'Datum a čas',
'date and time of creation' => 'Datum a čas vytvoření',
......
'e-mail variables have been successfully updated' => 'Proměnné e-mailu byly úspěšně aktualizovány.',
'e-mail variables havent been successfully updated' => 'Proměnné e-mailu nebyly úspěšně aktualizovány.',
'enable integrity test (all numbers in invoice has to be in extended statement)' => 'Povolit test na celistvost (každé číslo ve faktuře musí být v podrobném výpisu)',
'enable mysql event scheduler' => 'Povolit MySQL plánovač akcí',
'enabled' => 'Zapnuto',
'end membership' => 'Ukončit členství',
'end of month' => 'Konec měsíce',
......
'number of months' => 'Počet měsíců',
'number of the hours' => 'počet hodin',
'o' => 'V',
'object' => 'Objekt',
'october' => 'Říjen',
'of all approved work reports' => 'všech schválených pracovních výkazů',
'of all approved works' => 'všech schválených prací',
......
'show' => 'Zobrazit',
'show all confirmed works' => 'Zobraz všechnny potvrzené práce',
'show all invoices' => 'Zobrazit všechny faktury',
'show all logs' => 'Zobrazit všechny logy',
'show all messages' => 'Zobrazit všechnny zprávy',
'show all transfers on the account' => 'Ukaž všechny převody tohoto účtu',
'show all unconfirmed works' => 'Zobraz všechnny nepotvrzené práce',
......
'show transfers on this account' => 'Ukaž převody tohoto účtu',
'show unread messages' => 'Zobrazit nepřečtené zprávy',
'show user' => 'Ukaž uživatele',
'show user actions' => 'Zobraz uživatelovi akce',
'show voip account' => 'Zobrazit VoIP účet',
'show work' => 'Zobrazit práci',
'show work report' => 'Zobrazit pracovní výkaz',
......
'unlocked' => 'Odemčen',
'unlock invoice' => 'Odemčít fakturu',
'update' => 'Aktualizovat',
'updated' => 'Upraveno',
'upload bank transfers listing' => 'Nahrát bankovní výpis',
'url addresses without index' => 'URL adresy bez index.php.',
'url settings' => 'Nastavení URL',
......
'yes' => 'ano',
'you can simply open config-samplephp in a text editor, fill in your information, and save it as configphp' => 'Můžete jednoduše otevřít config-sample.php v textovém editoru, doplnit vaše údaje a uložit jej jako config.php.',
'you cannot vote twice about same work!' => 'Nemůžete hlasovat dvakrát o stejné práci!',
'you do not have required privilegies in database to perform this action' => 'Nemáte potřebná práva v databázi, pro provedení této akce',
'you are in debt' => 'Máte dluh',
'you have been successfully logged out' => 'Byl jste úspěšně odhlášen.',
'you have no permission to access redirection' => 'Nemáte práva k zobrazení přesměrování',
freenetis/branches/testing/application/i18n/cs_CZ/help.php
'entrance_fee' => 'Vstupní poplatek je jednorázový členský příspěvek, který je člen povinen zaplatit při vstupu do sdružení kromě případů, kdy je mu odpuštěn.',
'entrance_fee_instalment' => 'Splátka vstupního příspěvku je pro případ, kdy člen chce splácet vstupní příspěvek postupně. Zde nastavená částka mu bude každý měsíc stržena z jeho kreditního účtu. Pokud nechcete splátky využít, nechte výši splátky rovnu výši vstupního příspěvku.',
'gateway' => 'Určuje, zda-li je tato IP adresa bránou ve své podsíti. Typicky má toto nastavena každá IP adresa končící na jedničku v síti s prefixem 24.',
'gps_coordinates' => 'GPS souřadnice může být ve tvaru desetinného čísla, nebo: hodiny°minuty\'sekundy&quot.',
'mail_to_field' => 'Políčko bere jako vstup login uživatele, kterému chcete odeslat zprávu. Příjemců můžete uvést více, oddělte je čárkou.',
'member_name' => 'Vyplňujte v případě přidávání nějaké organizace. Pokud připojujete běžného člena, tak jako výsledné jméno člena se použije jeho jméno a příjmení.',
'never_redirect' => 'Zapnete-li tuto volbu, pak nebude možné tuto IP adresu nikdy přesměrovat běžným přesměrováním. Toto je vhodné zejména pro významné partnery jako jsou úřady, školy atd.',
freenetis/branches/testing/application/i18n/en_US/help.php
(
'approval_state' => 'State is in format Agree / Disagree / Abstain.',
'gps_coordinates' => 'GPS can be in shape of real number, or: hours°minutes\'seconds&quot.',
);
freenetis/branches/testing/application/helpers/gps.php
}
/**
* Render coordinate from MySQL point __toString()
* @return string $coordinates Rendered coordinates
* @param bool $use_html_entity If it is true °'" are return as HTML entity
*/
public static function degrees_from_str($coordinates, $use_html_entity)
{
if (mb_eregi("^[0-9]+\.[0-9]+ [0-9]+\.[0-9]+$", $coordinates))
{
$coordinates = explode(' ', $coordinates);
return gps::degrees($coordinates[0], $coordinates[1], $use_html_entity);
}
return "";
}
/**
* Check if degrees coordinate is valid
* @param string $degrees_coordinate Coordinate in form: degreesX°minuteX'secondX"
* @return bool
freenetis/branches/testing/application/helpers/callback.php
echo '<span style="color: red;">' . url_lang::lang('texts.Locked') . '</span>';
}
}
/**
* Callback field for user name of user given by id.
* @author Ondřej Fibich
* @param $item
* @param $name
*/
public static function user_id_log_field($item, $name)
{
$user = new User_Model($item->user_id);
if ($user->id)
{
echo html::anchor(
url_lang::base().'users/show/'.$user->id,
$user->name . ' ' . $user->surname
);
echo ' ' . html::anchor(
url_lang::base().'logs/show_by_user/'.$user->id,
html::image(array('src' => 'media/images/icons/history.png',
'title' => url_lang::lang('texts.Show user actions')))
);
}
else
{
echo $item->user_id;
}
}
/**
* Callback for action of log
* @author Ondřej Fibich
* @param $item
* @param $name
*/
public static function log_action_field($item, $name)
{
switch ($item->action)
{
case Log_Model::ACTION_ADD:
echo url_lang::lang('texts.Added');
break;
case Log_Model::ACTION_DELETE:
echo url_lang::lang('texts.Deleted');
break;
case Log_Model::ACTION_UPDATE:
echo url_lang::lang('texts.Updated');
break;
}
}
/**
* Callback for object of log
* @author Ondřej Fibich
* @param $item
* @param $name
*/
public static function object_log_field($item, $name)
{
echo html::anchor(
url_lang::base().'logs/show_object/'.$item->table_name.'/'.$item->object_id,
$item->object_id
);
}
/**
* Callback for values of log
* @author Ondřej Fibich
* @param $item
* @param $name
*/
public static function value_log_field($item, $name)
{
if (!empty($item->values))
{
$array = json_decode($item->values);
foreach ($array as $key => $value)
{
echo htmlspecialchars($key) .' = '.
htmlspecialchars($value) . '<br />';
}
}
}
/**
* Callback for display GPS
* @author Ondřej Fibich
* @param unknown_type $item
* @param string $name
*/
public static function gps_field($item, $name)
{
echo gps::degrees_from_str($item->gps, true);
}
}
freenetis/branches/testing/application/models/phone_invoice_user.php
{
// madness query to calculate price for each user invoicee
return $this->db->query(
"SELECT `phone_invoice_users`.`id`,
"SELECT p.tax_rate,
`phone_invoice_users`.`id`,
`phone_invoice_users`.`user_id`,
`phone_invoice_users`.`phone_number` ,
CONCAT( `users`.`surname`, ' ', `users`.`name` ) AS `name`,
......
WHERE phone_invoice_user_id =phone_invoice_users.id)
) AS price
FROM `phone_invoice_users`
LEFT JOIN `phone_invoices` p ON `p`.`id` = `phone_invoice_users`.`phone_invoice_id`
LEFT JOIN `users` ON `phone_invoice_users`.`user_id` = `users`.`id`
WHERE `phone_invoice_users`.`phone_invoice_id` = ?;",
array($invoice_id)
freenetis/branches/testing/application/models/user.php
public static $user = 2;
protected $belongs_to = array('member');
protected $has_many = array('jobs', 'devices', 'phone_invoices_users', 'users' => 'private_phone_contacts');
protected $has_many = array('jobs', 'devices', 'logs', 'phone_invoices_users', 'users' => 'private_phone_contacts');
protected $has_and_belongs_to_many = array('users_contacts' => 'contacts');
public $arr_sql = array('id' => 'u.id', 'name' => 'u.name', 'surname' => 'u.surname', 'login' => 'u.login', 'member_name' => 'm.name', 'email' => 'c.value');
freenetis/branches/testing/application/models/log.php
<?php
/**
* Model of logs.
* Table logs is handled as partitioned table, it needs at least MySQL ver. 5.1.
* Table partitions are created by scheduler.
* Logs are preserved for maximum of 30 days.
*
* @author Ondřej Fibich
* @property int $id
* @property int $user_id
* @property int $object_id
* @property string $table_name
* @property string $time
* @property string $values
*/
class Log_Model extends ORM
{
protected $belongs_to = array('user');
/** Logger action for adding record to the table */
const ACTION_ADD = 1;
/** Logger action for adding record to the table */
const ACTION_DELETE = 2;
/** Logger action for updating record to the table */
const ACTION_UPDATE = 3;
/**
* Contruct set logger
* @param int $id
*/
public function __construct($id = NULL)
{
parent::__construct($id);
// set action logger of
$this->set_logger(FALSE);
}
/**
* Add new partition for logs
* @author Ondřej Fibich
* @see Scheduler_Controller::logs_partitions_daily()
*/
public function add_partition()
{
$partition_name = date('Y_m_d', time());
$partition_date = date('Y-m-d', time() + 86400);
$this->db->query("
ALTER TABLE logs
ADD PARTITION (
PARTITION p_$partition_name
VALUES LESS THAN (TO_DAYS('$partition_date')
) ENGINE = InnoDB)
");
}
/**
* Remove partition for log which is 31 days old
* @author Ondřej Fibich
* @see Scheduler_Controller::logs_partitions_daily()
*/
public function remove_old_partition()
{
$partition_name = date('Y_m_d', time() - 86400 * 31);
$this->db->query("
ALTER TABLE logs
DROP PARTITION p_$partition_name
");
}
/**
* Insert all data from array in one query
* @author Ondřej Fibich
* @param array $logs_data Keys corresponds to table columns
*/
public function insert_all_logs($logs_data)
{
if (!is_array($logs_data) || !count($logs_data))
{
return;
}
$query = 'INSERT INTO logs (id, user_id, table_name, object_id, time, action, values) VALUES ';
foreach ($this->logger_cache as $log)
{
$query .= '(0, ' .intval($log['user_id']).
', \'' .$this->db->escape_str($log['table_name']).
'\', ' .intval($log['object_id']).
', \'' .$this->db->escape_str($log['time']).
'\', ' .intval($log['action']).
', \'' .$this->db->escape_str($log['values']). '\')';
}
// remove last ,
$query = substr($query, 0, mb_strlen($query) - 1);
$this->db->query($query);
}
/**
* Gets all users logs with limit
* @param int $offset
* @param int $limit
* @param int $user_id
* @return unknown_type
*/
public function get_all_users_logs($user_id, $offset, $limit)
{
return $this->db->query("
SELECT l.*
FROM logs l
WHERE user_id = ?
ORDER BY id DESC
LIMIT ?, ?
", $user_id, $offset, $limit);
}
/**
* Gets all objects logs with limit
* @param string $table_name
* @param int $object_id
* @param int $offset
* @param int $limit
* @return unknown_type
*/
public function get_all_object_logs($table_name, $object_id, $offset, $limit)
{
return $this->db->query("
SELECT l.*
FROM logs l
WHERE object_id = ? AND table_name = ?
ORDER BY id DESC
LIMIT ?, ?
", $object_id, $table_name, $offset, $limit);
}
/**
* Gets all logs with limit
* @param int $offset
* @param int $limit
* @param array $filter_values Filter for where contition
* @return unknown_type
*/
public function get_all_logs($offset, $limit, $filter_values = array())
{
// array of where conditions
$where = array();
// user id condition
if (isset($filter_values['user_id']))
{
$where[] = 'user_id='.intval($filter_values['user_id']);
}
// object id condition
if (isset($filter_values['object_id']))
{
$where[] = 'object_id='.intval($filter_values['object_id']);
}
// date condition
if (isset($filter_values['date_from']) || isset($filter_values['date_to']))
{
$from = @$filter_values['date_from'];
$to = @$filter_values['date_to'];
if (!preg_match('/^[0-9]{4,4}\-[0-9]{2,2}\-[0-9]{2,2}$/', $from))
{
// logs are persisted at max for 30 days
$from = date('Y-m-d', time() - 60*60*24*30);
}
if (!preg_match('/^[0-9]{4,4}\-[0-9]{2,2}\-[0-9]{2,2}$/', $to))
{
$to = date('Y-m-d', time());
}
$where[] = 'time BETWEEN \'' .$from. ' 00-00-00\' AND \'' .$to. ' 23:59:59\'';
}
// fill where contition
$where_str = count($where) ? 'WHERE ' . implode(' AND ', $where) : '';
// query
return $this->db->query("
SELECT l.*
FROM logs l
$where_str
ORDER BY id DESC
LIMIT ?, ?
", $offset, $limit);
}
/**
* Gets users list which are in logs for dropdown
* @return array
*/
public function select_list_users_which_has_logs()
{
$result = $this->db->query("
SELECT CONCAT(u.name,' ',u.surname) as username, u.id
FROM logs l
LEFT JOIN users u ON l.user_id = u.id
");
$ret_array = array();
foreach ($result as $r)
{
$ret_array[$r->id] = $r->username;
}
return $ret_array;
}
/**
* Gets number of logs
* @return int
*/
public function count_all_logs()
{
return $this->db->query("
SELECT COUNT(*) AS count FROM logs
")->current()->count;
}
/**
* Gets number of users logs
* @param int $user_id
* @return int
*/
public function count_all_users_logs($user_id)
{
return $this->db->query("
SELECT COUNT(*) AS count FROM logs WHERE user_id = ?
", $user_id)->current()->count;
}
/**
* Gets number of object logs
* @param string $table_name
* @param int $object_id
* @return int
*/
public function count_all_object_logs($table_name, $object_id)
{
return $this->db->query("
SELECT COUNT(*) AS count FROM logs WHERE table_name = ? AND object_id = ?
", $table_name, $object_id)->current()->count;
}
}
?>
freenetis/branches/testing/application/models/login_log.php
public function __construct($id = false)
{
parent::__construct($id);
// turn off action log
$this->set_logger(FALSE);
}
/**
freenetis/branches/testing/application/controllers/logs.php
<?php
/**
* Controller of logs.
* Table logs is handled as partitioned table, it needs at least MySQL ver. 5.1.
* Table partitions are created by scheduler.
* Logs are preserved for maximum of 30 days.
*
* @author Ondřej Fibich
*/
class Logs_Controller extends Controller
{
/**
* Redirects to show_all
* @author Ondřej Fibich
*/
public function index()
{
url::redirect(url_lang::base() . 'logs/show_all');
}
/**
* Show all actions logs and enable filter them.
* @author Ondřej Fibich
*/
public function show_all($limit_results = 100, $order_by = 'id', $order_by_direction = 'ASC', $page_word = null, $page = 1)
{
if (!$this->acl_check_view('Settings_Controller', 'system'))
Controller::error(ACCESS);
// gets new selector
if (is_numeric($this->input->get('record_per_page')))
$limit_results = (int) $this->input->get('record_per_page');
$log_model = new Log_Model();
$total_logs = $log_model->count_all_logs();
if (($sql_offset = ($page - 1) * $limit_results) > $total_logs)
$sql_offset = 0;
// users checkbox
$user_model = new User_Model();
// can be replaced by Log::select_list_users_which_has_logs()
$users = $user_model->get_all_user_names();
$users_array = array ('0' => '');
foreach ($users as $user)
{
$users_array[$user->id] = $user->username . ' (' . $user->id . ')';
}
// creates fields for filtering logs
$filter = new Table_Form(url_lang::base() . 'logs/show_all', 'get', array
(
new Table_Form_Item('text', 'object_id', 'Object'),
new Table_Form_Item('select', 'user_id', 'User', $users_array, array('style' => 'width: 207px')),
'tr',
new Table_Form_Item('text', 'date_from', 'Date from', NULL, array('id' => 'date_from')),
new Table_Form_Item('text', 'date_to', 'Date to', NULL, array('id' => 'date_to')),
'tr',
'td',
new Table_Form_Item('submit','submit','Filter')
));
// load logs
$logs = $log_model->get_all_logs($sql_offset, (int) $limit_results, $filter->values());
$arr_gets = array();
foreach ($this->input->get() as $key=>$value)
$arr_gets[] = $key.'='.$value;
$query_string = '?'.implode('&',$arr_gets);
// title of view
$title = url_lang::lang('texts.Action logs');
// create grid
$grid = new Grid(url_lang::base() . 'logs/show_all', $title, array
(
'use_paginator' => true,
'use_selector' => true,
'current' => $limit_results, //current selected 'records_per_page' value
'selector_increace' => 200, // increace
'selector_min' => 200, // minimum where selector start
'selector_max_multiplier' => 10,
'uri_segment' => 'page', // pass a string as uri_segment to trigger former 'label' functionality
'base_url' => Config::get('lang') . '/logs/show_all/' . $limit_results,
'total_items' => $total_logs, // use db count query here of course
'items_per_page' => $limit_results, // it may be handy to set defaults for stuff like this in config/pagination.php
'style' => 'classic',
'order_by' => 'id',
'order_by_direction' => 'DESC',
'limit_results' => $limit_results,
'query_string' => $query_string,
'filter' => $filter->view
));
$grid->field('id')->label(url_lang::lang('texts.Id'));
$grid->callback_field('user_id')->label(url_lang::lang('texts.User'))->callback('callback::user_id_log_field');
$grid->callback_field('action')->label(url_lang::lang('texts.Action'))->callback('callback::log_action_field');
$grid->field('table_name')->label(url_lang::lang('texts.Table'));
$grid->callback_field('object_id')->label(url_lang::lang('texts.Object'))->callback('callback::object_log_field');
$grid->field('time')->label(url_lang::lang('texts.Time'));
$grid->datasource($logs);
$view = new View('main');
// @todo replace this javascript with somenting smarter ;-)
$view->extra_scripts .= "
$(document).ready(function () {
$('#date_from, #date_to').datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: false,
changeYear: false,
minDate: -30,
maxDate: 0
});
$.datepicker.regional['" . Config::get('lang') . "'];
});";
$view->title = url_lang::lang('texts.Action logs');
$view->content = $grid;
$view->render(TRUE);
}
/**
* Show logs of user
* @author Ondřej Fibich
*/
function show_by_user($user_id = null, $limit_results = 200, $order_by = 'time', $order_by_direction = 'desc', $page_word = null, $page = 1)
{
if (!$this->acl_check_view('Settings_Controller', 'system'))
Controller::error(ACCESS);
if (!isset($user_id))
Controller::warning(PARAMETER);
$user = new User_Model((int) $user_id);
if (!$user->id)
Controller::error(RECORD);
// gets new selector
if (is_numeric($this->input->get('record_per_page')))
$limit_results = (int) $this->input->get('record_per_page');
$log_model = new Log_Model();
$total_logs = $log_model->count_all_users_logs($user_id);
if (($sql_offset = ($page - 1) * $limit_results) > $total_logs)
$sql_offset = 0;
$title = url_lang::lang('texts.Action logs of user') . ' ' . $user->name . ' ' . $user->surname;
// load logs
$logs = $log_model->get_all_users_logs($user->id, $sql_offset, (int) $limit_results);
// create grid
$grid = new Grid(url_lang::base() . 'logs/show_all', $title, array(
//'separator' => '',
'use_paginator' => true,
'use_selector' => true,
'current' => $limit_results, //current selected 'records_per_page' value
'selector_increace' => 200, // increace
'selector_min' => 200, // minimum where selector start
'selector_max_multiplier' => 10,
'uri_segment' => 'page', // pass a string as uri_segment to trigger former 'label' functionality
'base_url' => Config::get('lang') . '/logs/show_all/' . $limit_results,
'total_items' => $total_logs, // use db count query here of course
'items_per_page' => $limit_results, // it may be handy to set defaults for stuff like this in config/pagination.php
'style' => 'classic',
'order_by' => 'id',
'order_by_direction' => 'DESC',
'limit_results' => $limit_results
));
$grid->field('id')->label(url_lang::lang('texts.Id'));
$grid->callback_field('user_id')->label(url_lang::lang('texts.User'))->callback('callback::user_id_log_field');
$grid->callback_field('action')->label(url_lang::lang('texts.Action'))->callback('callback::log_action_field');
$grid->field('table_name')->label(url_lang::lang('texts.Table'));
$grid->callback_field('object_id')->label(url_lang::lang('texts.Object'))->callback('callback::object_log_field');
$grid->field('time')->label(url_lang::lang('texts.Time'));
$grid->datasource($logs);
$view = new View('main');
$view->title = url_lang::lang('texts.Action logs');
$view->content = new View('show_all');
$view->content->headline = url_lang::lang('texts.Action logs');
$view->content->table = $grid;
$view->content->link_back = html::anchor(url_lang::base() . 'logs/show_all', url_lang::lang('texts.Show all logs'));
$view->render(TRUE);
}
/**
* Show logs of user
* @author Ondřej Fibich
*/
function show_object($table, $object_id = null, $limit_results = 200, $order_by = 'time', $order_by_direction = 'desc', $page_word = null, $page = 1)
{
if (!$this->acl_check_view('Settings_Controller', 'system'))
Controller::error(ACCESS);
if (!is_numeric($object_id) || !is_string($table))
Controller::warning(PARAMETER);
// gets new selector
if (is_numeric($this->input->get('record_per_page')))
$limit_results = (int) $this->input->get('record_per_page');
$log_model = new Log_Model();
$total_logs = $log_model->count_all_object_logs($table, $object_id);
if (($sql_offset = ($page - 1) * $limit_results) > $total_logs)
$sql_offset = 0;
$title = url_lang::lang('texts.Action logs of object');
// load logs
$logs = $log_model->get_all_object_logs($table, $object_id, $sql_offset, (int) $limit_results);
// create grid
$grid = new Grid(url_lang::base() . 'logs/show_all', $title, array
(
'use_paginator' => true,
'use_selector' => true,
'current' => $limit_results, //current selected 'records_per_page' value
'selector_increace' => 200, // increace
'selector_min' => 200, // minimum where selector start
'selector_max_multiplier' => 10,
'uri_segment' => 'page', // pass a string as uri_segment to trigger former 'label' functionality
'base_url' => Config::get('lang') . '/logs/show_all/' . $limit_results,
'total_items' => $total_logs, // use db count query here of course
'items_per_page' => $limit_results, // it may be handy to set defaults for stuff like this in config/pagination.php
'style' => 'classic',
'order_by' => 'id',
'order_by_direction' => 'DESC',
'limit_results' => $limit_results
));
$grid->field('id')->label(url_lang::lang('texts.Id'));
$grid->callback_field('user_id')->label(url_lang::lang('texts.User'))->callback('callback::user_id_log_field');
$grid->callback_field('action')->label(url_lang::lang('texts.Action'))->callback('callback::log_action_field');
$grid->field('table_name')->label(url_lang::lang('texts.Table'));
$grid->callback_field('object_id')->label(url_lang::lang('texts.Object'))->callback('callback::object_log_field');
$grid->field('time')->label(url_lang::lang('texts.Time'));
$grid->callback_field('values')->label(url_lang::lang('texts.Changed values'))->callback('callback::value_log_field');
$grid->datasource($logs);
$view = new View('main');
$view->title = url_lang::lang('texts.Action logs');
$view->content = new View('show_all');
$view->content->headline = url_lang::lang('texts.Action logs');
$view->content->table = $grid;
$view->content->link_back = html::anchor(url_lang::base() . 'logs/show_all', url_lang::lang('texts.Show all logs'));
$view->render(TRUE);
}
}
freenetis/branches/testing/application/controllers/address_points.php
$grid->order_field('town')->label(url_lang::lang('texts.town'));
$grid->order_field('quarter')->label(url_lang::lang('texts.quarter'));
$grid->order_field('zip_code')->label(url_lang::lang('texts.zip_code'));
$grid->order_callback_field('gps')->label(url_lang::lang('texts.gps'))->callback('Address_points_Controller::gps_field');
$grid->order_callback_field('gps')->label(url_lang::lang('texts.gps'))->callback('callback::gps_field');
if ($this->acl_check_view(get_class($this), 'address_point'))
$grid->action_field('id') ->label(url_lang::lang('texts.Show')) ->url(url_lang::base().'address_points/show') ->action(url_lang::lang('texts.Show'));
......
$form = new Forge(url_lang::base().'address_points/add/', '', 'POST', array('id' => 'article_form'));
$form->set_attr('class', 'form_class')->set_attr('method', 'post');
$form->dropdown('country_id')->label(url_lang::lang('texts.country').':')->rules('required')->options($arr_countries);
$form->dropdown('country_id')->label(url_lang::lang('texts.country').':')->rules('required')->options($arr_countries)->selected(Settings::get('default_country'));
$form->dropdown('street_id')->label(url_lang::lang('texts.street').':')->rules('required')->options($arr_streets);
$form->input('street_number')->label(url_lang::lang('texts.street number').':')->rules('required|length[1,50]|valid_numeric');
$form->dropdown('town_id')->label(url_lang::lang('texts.town').':')->rules('required')->options($arr_towns);
$form->input('gpsx')->label(url_lang::lang('texts.gps').' X:')->rules('gps');
$form->input('gpsy')->label(url_lang::lang('texts.gps').' Y:')->rules('gps');
$form->input('gpsx')->label(url_lang::lang('texts.gps').' X:&nbsp;'.help::hint('gps_coordinates'))->rules('gps');
$form->input('gpsy')->label(url_lang::lang('texts.gps').' Y:&nbsp;'.help::hint('gps_coordinates'))->rules('gps');
$form->submit('submit')->value(url_lang::lang('texts.Edit'));
special::required_forge_style($form, ' *', 'required');
......
$form->dropdown('street_id')->label(url_lang::lang('texts.street').':')->options($arr_streets)->selected($address_point->street_id)->disabled('disabled');;
$form->input('street_number')->label(url_lang::lang('texts.street number').':')->value($address_point->street_number)->disabled('disabled');
$form->dropdown('town_id')->label(url_lang::lang('texts.town').':')->options($arr_towns)->selected($address_point->town_id)->disabled('disabled');
$form->input('gpsx')->label(url_lang::lang('texts.gps').' X:')->rules('required|gps')->value($gpsx);
$form->input('gpsy')->label(url_lang::lang('texts.gps').' Y:')->rules('required|gps')->value($gpsy);
$form->input('gpsx')->label(url_lang::lang('texts.gps').' X:&nbsp;'.help::hint('gps_coordinates'))->rules('required|gps')->value($gpsx);
$form->input('gpsy')->label(url_lang::lang('texts.gps').' Y:&nbsp;'.help::hint('gps_coordinates'))->rules('required|gps')->value($gpsy);
if (! empty ($address_point->gps))
{
$form->gpsx->disabled('disabled');
freenetis/branches/testing/application/controllers/phone_invoices.php
$data = Parser_Vodafone_Invoice::parse($form->parse->value, $integrity_test);
$phone_invoice = new Phone_invoice_Model();
$phone_invoice->set_logger(FALSE);
$phone_invoice->date_of_issuance = $data->date_of_issuance->format('Y-m-d');
$phone_invoice->billing_period_from = $data->billing_period_from->format('Y-m-d');
$phone_invoice->billing_period_to = $data->billing_period_to->format('Y-m-d');
......
$phone_inv_user_model = new Phone_invoice_user_Model();
$query = $phone_inv_user_model->get_all_invoice_users($phone_invoice->id);
$query2 = array();
// add price with tax
foreach ($query as $i => $q)
{
$q->price_vat = $q->price * (1 + $q->tax_rate / 100);
$query2[$i] = $q;
}
$grid->field('id')->label(url_lang::lang('texts.ID'));
$grid->field('phone_number')->label(url_lang::lang('texts.Phone number'));
$grid->callback_field('user')->label(url_lang::lang('texts.User'))
->callback('Phone_invoices_Controller::user_field');
$grid->callback_field('price')->label(url_lang::lang('texts.Price out of tax'))
->callback('callback::phone_price_field');
$grid->callback_field('price_vat')->label(url_lang::lang('texts.Price vat'))
->callback('callback::phone_price_field');
$grid->action_field('id')->label(url_lang::lang('texts.Show details'))
->url(url_lang::base().'phone_invoices/show_details')
->action(url_lang::lang('texts.Show'));
......
->action(url_lang::lang('texts.Delete'))->class('a_delete');
}
$grid->datasource($query);
$grid->datasource($query2);
$view = new View('main');
......
foreach ($data->bill_numbers as $services)
{
$phone_inv_user = new Phone_invoice_user_Model();
$phone_inv_user->set_logger(FALSE);
$phone_inv_user->user_id = strval(self::user_number_cache($services->number));
$phone_inv_user->phone_invoice_id = $phone_invoice->id;
$phone_inv_user->phone_number = $services->number;
......
foreach ($services->calls as $item)
{
$model = new Phone_call_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
......
foreach ($services->fixed_calls as $item)
{
$model = new Phone_fixed_call_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
......
foreach ($services->vpn_calls as $item)
{
$model = new Phone_vpn_call_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
......
foreach ($services->smss as $item)
{
$model = new Phone_sms_message_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
......
foreach ($services->roaming_smss as $item)
{
$model = new Phone_roaming_sms_message_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
......
foreach ($services->internet as $item)
{
$model = new Phone_connection_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
......
foreach ($services->pays as $item)
{
$model = new Phone_pay_Model();
$model->set_logger(FALSE);
$model->phone_invoice_user_id = $phone_inv_user->id;
$model->datetime = $item->date_time->format('Y-m-d H:i:s');
$model->price = $item->price;
freenetis/branches/testing/application/controllers/scheduler.php
$member_model->update_lock_status();
}
// manage logs
if ((date('H:i') == '00:00'))
{
self::logs_partitions_daily();
}
//send quened SMS
self::send_quened_sms();
......
}
/**
* Manage partitions of log table.
* Add partition for current day and removes 31 days old partition.
* @author Ondřej Fibich
*/
private function logs_partitions_daily()
{
$model_log = new Log_Model();
// add partition for today
$model_log->add_partition();
// remove log partition
try
{
$model_log->remove_old_partition();
}
catch (Exception $ignore)
{ // ignore exception - first 30 days do not have older one..
}
}
/**
* Function sends SMS messages from db quene.
* @author Roman Sevcik
*/
freenetis/branches/testing/application/controllers/import.php
}
// save bank statement
$statement = new Bank_statement_Model();
$statement->set_logger(FALSE);
$statement->bank_account_id = $id;
$statement->user_id = $this->session->get('user_id');
$statement->statement_number = $form_data['statement_number'];
......
// ***Tady si vytvorime instanci účtu clena (nebo dodavatele) z prave nacteneho vypisu:
$bank_acc = $this->bank_acc_model->where(array('account_nr' => $data->account_nr, 'bank_nr' => $data->account_bank_nr))->find();
if (!$bank_acc->id) { // bank. ucet clena neexistuje, tak si ho vytvorime
if (!$bank_acc->id) { // bank. ucet clena neexistuje, tak si ho vytvorime
$bank_acc->set_logger(FALSE);
$bank_acc->clear();
$bank_acc->member_id = $member->id;
$bank_acc->name = $data->name;
......
$credit_acc = $this->acc_model->where(array('member_id' => $member->id, 'account_attribute_id' => Account_attribute_Model::$credit))->find();
if (!$credit_acc->id)
{
$credit_acc->clear();
$credit_acc->clear();
$credit_acc->set_logger(FALSE);
$credit_acc->account_attribute_id = Account_attribute_Model::$credit;
$credit_acc->member_id = $member->id;
$credit_acc->name = $member->name;
......
$bank_acc=$bank_acc_model->where(array('account_nr' => $data->account_nr, 'bank_nr' => $data->account_bank_nr))->find();
if (!$bank_acc->id) { // bank. ucet clena neexistuje, tak si ho vytvorime
$bank_acc->clear();
$bank_acc->set_logger(FALSE);
$bank_acc->member_id = ($term_vklad ? 1 : $member->id); //term. vklad je vždy způsoben sdružením
$bank_acc->name = $data->name;
$bank_acc->account_nr = $data->account_nr;
......
// ten účet ale musíme najít nebo vytvořit:
$credit_acc=$acc_model->where(array('member_id' => $member->id, 'account_attribute_id' => Account_attribute_Model::$credit))->find();
if (!$credit_acc->id) {
$credit_acc->clear();
$credit_acc->clear();
$credit_acc->set_logger(FALSE);
$credit_acc->account_attribute_id = Account_attribute_Model::$credit;
$credit_acc->member_id = $member->id;
/**
......
{
// duplicity check - in case of duplicity all already imported items are storned
$bank_transfer = new Bank_transfer_Model();
$bank_transfer->set_logger(FALSE);
$dups = $bank_transfer->get_duplicities($data);
if ($dups->count() > 0)
throw new Duplicity_Exception();
freenetis/branches/testing/application/upgrade_sql/upgrade_sql.php
return $svnid;
}
//////////////////////////////////////////////////////////////////////////////
// Remove phone, email columns in users table with transformation of data
// to the table contacts and its relations tables
// @author Ondřej Fibich
//////////////////////////////////////////////////////////////////////////////
function upgrade_sql_before()
{
$contact = new Contact_Model();
$default_country = new Country_Model(Settings::get('default_country'));
if (!$default_country || !$default_country->id)
{
return false;
}
try
{
// transaction
$contact->transaction_start();
$users = ORM::factory('user')->find_all();
foreach ($users as $user)
{
$email = trim($user->email);
$phone = trim($user->phone);
////////////////////////////////////////////////////////
// EMAIL
// is there something to add?
if (!empty($email))
{
$contact_id = $contact->find_contact_id(
Contact_Model::TYPE_EMAIL, $email
);
// contact is not in database?
if (!$contact_id)
{
// clear contact
$contact->clear();
// add contact
$contact->type = Contact_Model::TYPE_EMAIL;
$contact->value = $email;
$contact->save_throwable();
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
else
{
$contact = $contact->find($contact_id);
// is already users contact?
if (!$contact->is_users_contact($user->id))
{
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
}
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
////////////////////////////////////////////////////////
// PHONE
// is there something to add?
if (!empty($phone))
{
$contact_id = $contact->find_contact_id(
Contact_Model::TYPE_PHONE, $phone
);
// contact is not in database?
if (!$contact_id)
{
$prefix = false;
// clear contact
$contact->clear();
// has prefix?
if (mb_strlen($phone) > 9)
{
$prefix = $contact->find_phone_country_code($phone);
// remove prefix
$phone = mb_substr($phone, mb_strlen($prefix));
}
// add contact
$contact->type = Contact_Model::TYPE_PHONE;
$contact->value = $phone;
$contact->save_throwable();
// add country
if ($prefix)
{ // not default country
$country_id = $contact->find_phone_country($prefix.$phone);
$country = new Country_Model($country_id);
$contact->add($country);
}
else
{
$contact->add($default_country);
}
$contact->save_throwable();
// add relation between user and phone
$user->add($contact);
$user->save_throwable();
}
else
{
$contact = $contact->find($contact_id);
// is already users contact?
if (!$contact->is_users_contact($user->id))
{
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
}
}
}
// commit
$contact->transaction_commit();
}
catch (Exception $e)
{
$contact->transaction_rollback();
return false;
}
return true;
}
// array of sql queries that upgrade database
$upgrade_sql[get_SVN_rev()] = array(
// delete phone column
"ALTER TABLE users DROP phone",
// drop old log table
"DROP TABLE `logs`;",
// delete emial column
"ALTER TABLE users DROP email"
// create new table which have got partitions and NO indexes
"CREATE TABLE IF NOT EXISTS `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`table_name` varchar(255) COLLATE utf8_czech_ci NOT NULL,
`values` text COLLATE utf8_czech_ci,
`time` datetime NOT NULL,
`action` tinyint(2) NOT NULL DEFAULT '1',
`object_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci
PARTITION BY RANGE (TO_DAYS(`time`))
(PARTITION p_first VALUES LESS THAN (TO_DAYS('1970-01-01')) ENGINE = InnoDB);",
);
?>
freenetis/branches/testing/application/upgrade_sql/upgrade_sql_842.php
<?php
//////////////////////////////////////////////////////////////////////////////
// Remove phone, email columns in users table with transformation of data
// to the table contacts and its relations tables
// @author Ondřej Fibich
//////////////////////////////////////////////////////////////////////////////
function upgrade_sql_842_before()
{
$contact = new Contact_Model();
$default_country = new Country_Model(Settings::get('default_country'));
if (!$default_country || !$default_country->id)
{
return false;
}
try
{
// transaction
$contact->transaction_start();
$users = ORM::factory('user')->find_all();
foreach ($users as $user)
{
$email = trim($user->email);
$phone = trim($user->phone);
////////////////////////////////////////////////////////
// EMAIL
// is there something to add?
if (!empty($email))
{
$contact_id = $contact->find_contact_id(
Contact_Model::TYPE_EMAIL, $email
);
// contact is not in database?
if (!$contact_id)
{
// clear contact
$contact->clear();
// add contact
$contact->type = Contact_Model::TYPE_EMAIL;
$contact->value = $email;
$contact->save_throwable();
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
else
{
$contact = $contact->find($contact_id);
// is already users contact?
if (!$contact->is_users_contact($user->id))
{
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
}
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
////////////////////////////////////////////////////////
// PHONE
// is there something to add?
if (!empty($phone))
{
$contact_id = $contact->find_contact_id(
Contact_Model::TYPE_PHONE, $phone
);
// contact is not in database?
if (!$contact_id)
{
$prefix = false;
// clear contact
$contact->clear();
// has prefix?
if (mb_strlen($phone) > 9)
{
$prefix = $contact->find_phone_country_code($phone);
// remove prefix
$phone = mb_substr($phone, mb_strlen($prefix));
}
// add contact
$contact->type = Contact_Model::TYPE_PHONE;
$contact->value = $phone;
$contact->save_throwable();
// add country
if ($prefix)
{ // not default country
$country_id = $contact->find_phone_country($prefix.$phone);
$country = new Country_Model($country_id);
$contact->add($country);
}
else
{
$contact->add($default_country);
}
$contact->save_throwable();
// add relation between user and phone
$user->add($contact);
$user->save_throwable();
}
else
{
$contact = $contact->find($contact_id);
// is already users contact?
if (!$contact->is_users_contact($user->id))
{
// add relation between user and email
$user->add($contact);
$user->save_throwable();
}
}
}
}
// commit
$contact->transaction_commit();
}
catch (Exception $e)
{
$contact->transaction_rollback();
return false;
}
return true;
}
// array of sql queries that upgrade database
$upgrade_sql[842] = array(
// delete phone column
"ALTER TABLE users DROP phone",
// delete emial column
"ALTER TABLE users DROP email"
);
?>
freenetis/branches/testing/application/libraries/Parser_Vodafone_Invoice.php
try
{
// test služeb čísla na kompletnost
foreach ($test as $v)
foreach ($test as $i => $v)
{
if ($v < 0)
{
freenetis/branches/testing/application/libraries/MY_Controller.php
$this->db = new Database();
$config = new Config_Model();
// check if database has need version
$version = trim($this->db->query("SELECT VERSION() as version")->current()->version);
// transform mysql version to form x.x.x
if (mb_eregi('^([0-9]+\.[0-9]+\.[0-9]+)', $version, $r))
{
// At least MySQL v. 5.1.0 is required
if (version_compare($r[1], '5.1.0', '<'))
{
throw new Exception('Upgrade error: Your database is old, upgrade MySQL at least to version <b>5.1</b>');
}
}
// for each revision
for ($i = ($from_version+1); $i<($this->current_svn_db_schema_version); $i++)
{
freenetis/branches/testing/application/libraries/Table_Form_Item.php
<?php
class Table_Form_Item {
public $type,$name,$label,$values;
public function __construct($type='text',$name=NULL,$label=NULL,$values=array())
{
/**
* Class represents element of Table_Form_item
* @author Tomas Dulik, Michal Kliment, Ondřej Fibich
*/
class Table_Form_Item
{
/** @var string $type Type of Item */
public $type;
/** @var string $name Name of Item */
public $name;
/** @var string $label Label of Item */
public $label;
/**
* @var array $values Values of Item - first index of array for
* all items types except select box,
* where whole array is used as options of element
*/
public $values;
/**
* @var array $artrs Attributs of HTML element, key of array is attribut name,
* value of array is his value
*/
public $attrs;
/**
* Contruct of Form Item
* @param string $type
* @param string $name
* @param string $label
* @param array $values
* @param array $attrs
*/
public function __construct($type='text',$name=NULL,$label=NULL,$values=array(),$attrs=array())
{
$this->type = $type;
$this->name = $name;
$this->label = $label;
$this->values = $values;
}
$this->values = $values;
$this->attrs = $attrs;
}
}
?>
freenetis/branches/testing/application/views/menu.php
<li><?php echo html::anchor(url_lang::base().'access_rights', url_lang::lang('texts.Access rights')) ?></li>
<li><?php echo html::anchor(url_lang::base().'fees', url_lang::lang('texts.Fees')) ?></li>
<li><?php echo html::anchor(url_lang::base().'login_logs', url_lang::lang('texts.Login logs')) ?></li>
<li><?php echo html::anchor(url_lang::base().'logs', url_lang::lang('texts.Action logs')) ?></li>
<li><?php echo html::anchor(url_lang::base().'stats', url_lang::lang('texts.Stats')) ?></li>
<li><?php echo html::anchor(url_lang::base().'translations', url_lang::lang('texts.Translations')) ?></li>
<li><?php echo html::anchor(url_lang::base().'enum_types', url_lang::lang('texts.Enumerations')) ?></li>
freenetis/branches/testing/application/views/users/contacts_import.php
endforeach; ?>
];
/** @var string */
var users_names_options;
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff