Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 1e8c793d

Přidáno uživatelem Michal Kliment před asi 9 roky(ů)

Release 1.1.8

Zobrazit rozdíly:

application/controllers/fees.php
$arr_from = date_parse_from_format(DateTime::ISO8601, $this->input->post('from'));
$arr_to = date_parse_from_format(DateTime::ISO8601, $this->input->post('to'));
$date_from = date::round_month($arr_from['day'], $arr_from['month'], $arr_from['year']);
$date_to = date::round_month($arr_to['day'], $arr_to['month'], $arr_to['year']);
// handle 9999-12-31 (#956)
if ($arr_to['year'] == 9999 && $arr_to['month'] == 12 && $arr_to['day'] == 31)
{
$date_to = '9999-12-31';
}
else
{
$date_to = date::round_month($arr_to['day'], $arr_to['month'], $arr_to['year']);
}
$diff = date::diff_month($date_to, $date_from);
if ($diff < 0)
application/controllers/registration.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/
*
*/
/**
* Controller performs user registration by him self.
*
* @package Controller
*/
class Registration_Controller extends Controller
{
/**
* Function to self-registration of candidates about membership (applicants
*
* @author Michal Kliment, Jiri Svitak, Ondřej Fibich
*/
public function index()
{
// if self-registration is not allow, redirect to login page
if (!$this->settings->get('self_registration') || $this->session->get('user_id', 0))
{
url::redirect('login');
}
// countries
$country_model = new Country_Model();
$arr_countries = $country_model->where('enabled', 1)->select_list('id', 'country_name');
// streets
$arr_streets = array
(
NULL => '--- ' . __('Without street') . ' ---'
) + ORM::factory('street')->select_list('id', 'street');
// towns with zip code and quarter
$arr_towns = array
(
NULL => '--- ' . __('Select town') . ' ---'
) + ORM::factory('town')->select_list_with_quater();
// list for phone prefixes
$phone_prefixes = $country_model->select_country_code_list();
// registration form
$form = new Forge('registration');
$form->group('Login data');
$form->input('login')
->label('Username')
->help(help::hint('login_name'))
->rules('required|length[5,20]')
->callback(array($this, 'valid_username'));
$pass_min_len = Settings::get('security_password_length');
$form->password('password')
->help(help::hint('password'))
->rules('required|length['.$pass_min_len.',50]')
->class('main_password');
$form->password('confirm_password')
->rules('required|length['.$pass_min_len.',50]')
->matches($form->password);
$form->group('Basic information');
$form->input('title1')
->label('Pre title')
->rules('length[3,40]');
$form->input('name')
->rules('required|length[3,30]');
$form->input('middle_name')
->rules('length[3,30]');
$form->input('surname')
->rules('required|length[3,60]');
$form->input('title2')
->label('Post title')
->rules('length[3,30]');
$form->date('birthday')
->label('Birthday')
->years(date('Y') - 100, date('Y'))
->rules('required');
$legalp_group = $form->group('Legal person innformation')->visible(FALSE);
$legalp_group->input('membername')
->label('Name of organization')
->rules('length[1,60]');
$legalp_group->input('organization_identifier')
->label('Organization identifier')
->rules('length[3,20]');
$form->group('Address');
$form->dropdown('country_id')
->label('Country')
->rules('required')
->options($arr_countries)
->selected(Settings::get('default_country'))
->style('width:200px');
$address_point_server_active = Address_points_Controller::is_address_point_server_active();
// If address database application is set show new form
if ($address_point_server_active)
{
$form->input('town')
->label(__('Town').' - '.__('District'))
->rules('required')
->class('join1');
$form->input('district')
->class('join2')
->rules('required');
$form->input('street')
->label('Street')
->rules('required');
$form->input('zip')
->label('Zip code')
->rules('required');
}
else
{
$form->dropdown('town_id')
->label('Town')
->rules('required')
->options($arr_towns)
->style('width:200px');
$form->dropdown('street_id')
->label('Street')
->options($arr_streets)
->style('width:200px');
$form->input('street_number')
->rules('length[1,50]');
}
$form->input('gpsx')
->label(__('GPS').'&nbsp;X:')
->help(help::hint('gps_coordinates'))
->rules('gps');
$form->input('gpsy')
->label(__('GPS').'&nbsp;Y:')
->help(help::hint('gps_coordinates'))
->rules('gps');
$form->group('Contact information');
$form->dropdown('phone_prefix')
->label('Phone')
->rules('required')
->options($phone_prefixes)
->selected(Settings::get('default_country'))
->class('join1')
->style('width:70px');
$form->input('phone')
->rules('required|length[9,40]')
->callback(array($this, 'valid_phone'))
->class('join2')
->style('width:180px');
$form->input('email')
->rules('required|length[3,100]|valid_email')
->callback(array($this, 'valid_email'))
->style('width:250px');
$form->group('Additional information');
$form->textarea('comment')
->class('comment_ta');
$form->submit('Register');
// posted form
if ($form->validate())
{
$user = new User_Model;
$form_data = $form->as_array();
$match = array();
// validate address
if ($address_point_server_active &&
(
!Address_points_Controller::is_address_point_valid(
$form_data['country_id'],
$form_data['town'],
$form_data['district'],
$form_data['street'],
$form_data['zip']
) ||
!preg_match('((ev\.č\.)?[0-9][0-9]*(/[0-9][0-9]*[a-zA-Z]*)*)', $form_data['street'], $match)
))
{
$form->street->add_error('required', __('Invalid address point.'));
}
else
{
if ($address_point_server_active)
{
$street = trim(preg_replace(' ((ev\.č\.)?[0-9][0-9]*(/[0-9][0-9]*[a-zA-Z]*)*)', '', $form_data['street']));
$number = $match[0];
}
try
{
// start transaction
$user->transaction_start();
$form_data = $form->as_array();
// gps
$gpsx = NULL;
$gpsy = NULL;
if (!empty($form_data['gpsx']) && !empty($form_data['gpsy']))
{
$gpsx = doubleval($form_data['gpsx']);
$gpsy = doubleval($form_data['gpsy']);
if (gps::is_valid_degrees_coordinate($form_data['gpsx']))
{
$gpsx = gps::degrees2real($form_data['gpsx']);
}
if (gps::is_valid_degrees_coordinate($form_data['gpsy']))
{
$gpsy = gps::degrees2real($form_data['gpsy']);
}
}
$member = new Member_Model;
$enum_type = new Enum_type_Model();
$user->login = $form_data['login'];
$user->password = sha1($form_data['password']);
$user->name = $form_data['name'];
$user->middle_name = $form_data['middle_name'];
$user->surname = $form_data['surname'];
$user->pre_title = $form_data['title1'];
$user->post_title = $form_data['title2'];
$user->birthday = date('Y-m-d', $form_data['birthday']);
$user->type = User_Model::MAIN_USER;
// entrance fee
$fee_model = new Fee_Model();
$fee = $fee_model->get_by_date_type(date('Y-m-d'), 'entrance fee');
if (is_object($fee) && $fee->id)
{
$entrance_fee = $fee->fee;
}
else
{
$entrance_fee = 0;
}
$address_point_model = new Address_point_Model();
if ($address_point_server_active)
{
$t = new Town_Model();
$s = new Street_Model();
$ap = new Address_point_Model();
$district = $form_data['district'];
if ($form_data['town'] == $form_data['district'])
{
$district = '';
}
$t_id = $t->get_town($form_data['zip'], $form_data['town'], $district)->id;
$s_id = $s->get_street($street, $t_id)->id;
$address_point = $ap->get_address_point($form_data['country_id'], $t_id, $s_id, $number);
}
else
{
$address_point = $address_point_model->get_address_point(
$form_data['country_id'], $form_data['town_id'],
$form_data['street_id'], $form_data['street_number'],
$gpsx, $gpsy
);
}
// address point doesn't exist exist, create it
if (!$address_point->id)
{
$address_point->save_throwable();
}
// add GPS
if (!empty($gpsx) && !empty($gpsy))
{ // save
$address_point->update_gps_coordinates(
$address_point->id, $gpsx, $gpsy
);
}
else
{ // delete gps
$address_point->gps = '';
$address_point->save_throwable();
}
// speed class
$speed_class_model = new Speed_class_Model();
$default_speed_class = $speed_class_model->get_applicants_default_class();
if ($default_speed_class)
{
$member->speed_class_id = $default_speed_class->id;
}
$member->name = ($form_data['membername'] != '') ?
$form_data['membername'] : $user->name . ' ' . $user->surname;
$member->address_point_id = $address_point->id;
$member->type = Member_Model::TYPE_APPLICANT;
$member->organization_identifier = $form_data['organization_identifier'];
$member->entrance_fee = $entrance_fee;
$member->applicant_registration_datetime = date('Y-m-d H:i:s');
$member->comment = $form_data['comment'];
$member->save_throwable();
$user->member_id = $member->id;
$user->save_throwable();
$member->user_id = $user->id;
$member->save_throwable();
// telephone
$contact = new Contact_Model();
$contact->type = Contact_Model::TYPE_PHONE;
$contact->value = $form_data['phone'];
$contact->save_throwable();
$contact->add($user);
$contact->save_throwable();
$phone_country = new Country_Model($form_data['phone_prefix']);
$contact->add($phone_country);
$contact->save_throwable();
$contact->clear();
// email
$contact->type = Contact_Model::TYPE_EMAIL;
$contact->value = $form_data['email'];
$contact->save_throwable();
$contact->add($user);
$contact->save_throwable();
// account
$account = new Account_Model();
$account->member_id = $member->id;
$account->account_attribute_id = Account_attribute_Model::CREDIT;
if ($form_data['membername'] == '')
$account->name = $form_data['surname'] . ' ' . $form_data['name'];
else
$account->name = $form_data['membername'];
$account->save_throwable();
// access rights of expectant for membership (wannabe - aro group 23)
$groups_aro_map = new Groups_aro_map_Model();
$groups_aro_map->aro_id = $user->id;
$groups_aro_map->group_id = Aro_group_Model::REGISTERED_APPLICANTS;
$groups_aro_map->save_throwable();
// commit transaction
$user->transaction_commit();
url::redirect('registration/complete');
}
catch (Exception $ex)
{
$user->transaction_rollback();
status::error('Cannot complete registration.', $ex);
Log::add_exception($ex);
}
}
}
$view = new View('registration/index');
$view->title = __('Registration form');
$view->form = $form->html();
$view->render(TRUE);
}
/**
* Info about registration after correct sending
*
* @author Ondřej Fibich
*/
public function complete()
{
$view = new View('registration/done');
$view->render(TRUE);
}
/**
* Check if username is valid
*
* @param string $input
*/
public static function valid_username($input = NULL)
{
// validators cannot be accessed
if (empty($input) || !is_object($input))
{
self::error(PAGE);
}
$user_model = new User_Model();
$username_regex = Settings::get('username_regex');
if ($user_model->username_exist($input->value) && !trim($input->value) == '')
{
$input->add_error('required', __('Username already exists in database'));
}
else if (preg_match($username_regex, $input->value) == 0)
{
$input->add_error(
'required', __('Login must contains only a-z and 0-9 and starts with literal.')
);
}
}
/**
* Check if phone is valis
*
* @param string $input
*/
public static function valid_phone($input = NULL)
{
// validators cannot be accessed
if (empty($input) || !is_object($input))
{
self::error(PAGE);
}
$user_model = new User_Model();
if ($user_model->phone_exist($input->value) && !trim($input->value) == '')
{
$input->add_error('required', __('Phone already exists in database.'));
}
}
/**
* Check if email is valis
*
* @param string $input
*/
public static function valid_email($input = NULL)
{
// validators cannot be accessed
if (empty($input) || !is_object($input))
{
self::error(PAGE);
}
$user_model = new User_Model();
if ($user_model->email_exist($input->value) && !trim($input->value) == '')
{
$input->add_error('required', __('Email already exists in database.'));
}
}
}
<?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/
*
*/
/**
* Controller performs user registration by him self.
*
* @package Controller
*/
class Registration_Controller extends Controller
{
/**
* Function to self-registration of candidates about membership (applicants
*
* @author Michal Kliment, Jiri Svitak, Ondřej Fibich
*/
public function index()
{
// if self-registration is not allow, redirect to login page
if (!$this->settings->get('self_registration') || $this->session->get('user_id', 0))
{
url::redirect('login');
}
// countries
$country_model = new Country_Model();
$arr_countries = $country_model->where('enabled', 1)->select_list('id', 'country_name');
// streets
$arr_streets = array
(
NULL => '--- ' . __('Without street') . ' ---'
) + ORM::factory('street')->select_list('id', 'street');
// towns with zip code and quarter
$arr_towns = array
(
NULL => '--- ' . __('Select town') . ' ---'
) + ORM::factory('town')->select_list_with_quater();
// list for phone prefixes
$phone_prefixes = $country_model->select_country_code_list();
// registration form
$form = new Forge('registration');
$form->group('Login data');
$form->input('login')
->label('Username')
->help(help::hint('login_name'))
->rules('required|length[5,20]')
->callback(array($this, 'valid_username'));
$pass_min_len = Settings::get('security_password_length');
$form->password('password')
->help(help::hint('password'))
->rules('required|length['.$pass_min_len.',50]')
->class('main_password');
$form->password('confirm_password')
->rules('required|length['.$pass_min_len.',50]')
->matches($form->password);
$form->group('Basic information');
$form->input('title1')
->label('Pre title')
->rules('length[3,40]');
$form->input('name')
->rules('required|length[3,30]');
$form->input('middle_name')
->rules('length[3,30]');
$form->input('surname')
->rules('required|length[3,60]');
$form->input('title2')
->label('Post title')
->rules('length[3,30]');
$form->date('birthday')
->label('Birthday')
->years(date('Y') - 100, date('Y'))
->rules('required');
$legalp_group = $form->group('Legal person innformation')->visible(FALSE);
$legalp_group->input('membername')
->label('Name of organization')
->rules('length[1,60]');
$legalp_group->input('organization_identifier')
->label('Organization identifier')
->rules('length[3,20]');
$form->group('Address');
$form->dropdown('country_id')
->label('Country')
->rules('required')
->options($arr_countries)
->selected(Settings::get('default_country'))
->style('width:200px');
$address_point_server_active = Address_points_Controller::is_address_point_server_active();
// If address database application is set show new form
if ($address_point_server_active)
{
$form->input('town')
->label(__('Town').' - '.__('District'))
->rules('required')
->class('join1');
$form->input('district')
->class('join2')
->rules('required');
$form->input('street')
->label('Street')
->rules('required');
$form->input('zip')
->label('Zip code')
->rules('required');
}
else
{
$form->dropdown('town_id')
->label('Town')
->rules('required')
->options($arr_towns)
->style('width:200px');
$form->dropdown('street_id')
->label('Street')
->options($arr_streets)
->style('width:200px');
$form->input('street_number')
->rules('length[1,50]');
}
$form->input('gpsx')
->label(__('GPS').'&nbsp;X:')
->help(help::hint('gps_coordinates'))
->rules('gps');
$form->input('gpsy')
->label(__('GPS').'&nbsp;Y:')
->help(help::hint('gps_coordinates'))
->rules('gps');
$form->group('Contact information');
$form->dropdown('phone_prefix')
->label('Phone')
->rules('required')
->options($phone_prefixes)
->selected(Settings::get('default_country'))
->class('join1')
->style('width:70px');
$form->input('phone')
->rules('required|length[9,40]')
->callback(array($this, 'valid_phone'))
->class('join2')
->style('width:180px');
$form->input('email')
->rules('required|length[3,100]|valid_email')
->callback(array($this, 'valid_email'))
->style('width:250px');
$form->group('Additional information');
$form->textarea('comment')
->class('comment_ta');
$form->submit('Register');
// posted form
if ($form->validate())
{
$user = new User_Model;
$form_data = $form->as_array();
$match = array();
// validate address
if ($address_point_server_active &&
(
!Address_points_Controller::is_address_point_valid(
$form_data['country_id'],
$form_data['town'],
$form_data['district'],
$form_data['street'],
$form_data['zip']
) ||
!preg_match('((ev\.č\.)?[0-9][0-9]*(/[0-9][0-9]*[a-zA-Z]*)*)', $form_data['street'], $match)
))
{
$form->street->add_error('required', __('Invalid address point.'));
}
else
{
if ($address_point_server_active)
{
$street = trim(preg_replace(' ((ev\.č\.)?[0-9][0-9]*(/[0-9][0-9]*[a-zA-Z]*)*)', '', $form_data['street']));
$number = $match[0];
}
try
{
// start transaction
$user->transaction_start();
$form_data = $form->as_array();
// gps
$gpsx = NULL;
$gpsy = NULL;
if (!empty($form_data['gpsx']) && !empty($form_data['gpsy']))
{
$gpsx = doubleval($form_data['gpsx']);
$gpsy = doubleval($form_data['gpsy']);
if (gps::is_valid_degrees_coordinate($form_data['gpsx']))
{
$gpsx = gps::degrees2real($form_data['gpsx']);
}
if (gps::is_valid_degrees_coordinate($form_data['gpsy']))
{
$gpsy = gps::degrees2real($form_data['gpsy']);
}
}
$member = new Member_Model;
$enum_type = new Enum_type_Model();
$user->login = $form_data['login'];
$user->password = sha1($form_data['password']);
$user->name = $form_data['name'];
$user->middle_name = $form_data['middle_name'];
$user->surname = $form_data['surname'];
$user->pre_title = $form_data['title1'];
$user->post_title = $form_data['title2'];
$user->birthday = date('Y-m-d', $form_data['birthday']);
$user->type = User_Model::MAIN_USER;
// entrance fee
$fee_model = new Fee_Model();
$fee = $fee_model->get_by_date_type(date('Y-m-d'), 'entrance fee');
if (is_object($fee) && $fee->id)
{
$entrance_fee = $fee->fee;
}
else
{
$entrance_fee = 0;
}
$address_point_model = new Address_point_Model();
if ($address_point_server_active)
{
$t = new Town_Model();
$s = new Street_Model();
$ap = new Address_point_Model();
$district = $form_data['district'];
if ($form_data['town'] == $form_data['district'])
{
$district = '';
}
$t_id = $t->get_town($form_data['zip'], $form_data['town'], $district)->id;
$s_id = $s->get_street($street, $t_id)->id;
$address_point = $ap->get_address_point($form_data['country_id'], $t_id, $s_id, $number);
}
else
{
$address_point = $address_point_model->get_address_point(
$form_data['country_id'], $form_data['town_id'],
$form_data['street_id'], $form_data['street_number'],
$gpsx, $gpsy
);
}
// address point doesn't exist exist, create it
if (!$address_point->id)
{
$address_point->save_throwable();
}
// add GPS
if (!empty($gpsx) && !empty($gpsy))
{ // save
$address_point->update_gps_coordinates(
$address_point->id, $gpsx, $gpsy
);
}
else
{ // delete gps
$address_point->gps = '';
$address_point->save_throwable();
}
// speed class
$speed_class_model = new Speed_class_Model();
$default_speed_class = $speed_class_model->get_applicants_default_class();
if ($default_speed_class)
{
$member->speed_class_id = $default_speed_class->id;
}
$member->name = ($form_data['membername'] != '') ?
$form_data['membername'] : $user->name . ' ' . $user->surname;
$member->address_point_id = $address_point->id;
$member->type = Member_Model::TYPE_APPLICANT;
$member->organization_identifier = $form_data['organization_identifier'];
$member->entrance_fee = $entrance_fee;
$member->applicant_registration_datetime = date('Y-m-d H:i:s');
$member->comment = $form_data['comment'];
$member->save_throwable();
$user->member_id = $member->id;
$user->save_throwable();
$member->user_id = $user->id;
$member->save_throwable();
// telephone
$contact = new Contact_Model();
$contact->type = Contact_Model::TYPE_PHONE;
$contact->value = $form_data['phone'];
$contact->save_throwable();
$contact->add($user);
$contact->save_throwable();
$phone_country = new Country_Model($form_data['phone_prefix']);
$contact->add($phone_country);
$contact->save_throwable();
$contact->clear();
// email
$contact->type = Contact_Model::TYPE_EMAIL;
$contact->value = $form_data['email'];
$contact->save_throwable();
$contact->add($user);
$contact->save_throwable();
// account
$account = new Account_Model();
$account->member_id = $member->id;
$account->account_attribute_id = Account_attribute_Model::CREDIT;
if ($form_data['membername'] == '')
$account->name = $form_data['surname'] . ' ' . $form_data['name'];
else
$account->name = $form_data['membername'];
$account->save_throwable();
// save allowed subnets count of member
$allowed_subnets_count = new Allowed_subnets_count_Model();
$allowed_subnets_count->member_id = $member->id;
$allowed_subnets_count->count = Settings::get('allowed_subnets_default_count');
$allowed_subnets_count->save_throwable();
// access rights of expectant for membership (wannabe - aro group 23)
$groups_aro_map = new Groups_aro_map_Model();
$groups_aro_map->aro_id = $user->id;
$groups_aro_map->group_id = Aro_group_Model::REGISTERED_APPLICANTS;
$groups_aro_map->save_throwable();
// commit transaction
$user->transaction_commit();
url::redirect('registration/complete');
}
catch (Exception $ex)
{
$user->transaction_rollback();
status::error('Cannot complete registration.', $ex);
Log::add_exception($ex);
}
}
}
$view = new View('registration/index');
$view->title = __('Registration form');
$view->form = $form->html();
$view->render(TRUE);
}
/**
* Info about registration after correct sending
*
* @author Ondřej Fibich
*/
public function complete()
{
$view = new View('registration/done');
$view->render(TRUE);
}
/**
* Check if username is valid
*
* @param string $input
*/
public static function valid_username($input = NULL)
{
// validators cannot be accessed
if (empty($input) || !is_object($input))
{
self::error(PAGE);
}
$user_model = new User_Model();
$username_regex = Settings::get('username_regex');
if ($user_model->username_exist($input->value) && !trim($input->value) == '')
{
$input->add_error('required', __('Username already exists in database'));
}
else if (preg_match($username_regex, $input->value) == 0)
{
$input->add_error(
'required', __('Login must contains only a-z and 0-9 and starts with literal.')
);
}
}
/**
* Check if phone is valis
*
* @param string $input
*/
public static function valid_phone($input = NULL)
{
// validators cannot be accessed
if (empty($input) || !is_object($input))
{
self::error(PAGE);
}
$user_model = new User_Model();
if ($user_model->phone_exist($input->value) && !trim($input->value) == '')
{
$input->add_error('required', __('Phone already exists in database.'));
}
}
/**
* Check if email is valis
*
* @param string $input
*/
public static function valid_email($input = NULL)
{
// validators cannot be accessed
if (empty($input) || !is_object($input))
{
self::error(PAGE);
}
$user_model = new User_Model();
if ($user_model->email_exist($input->value) && !trim($input->value) == '')
{
$input->add_error('required', __('Email already exists in database.'));
}
}
}
application/controllers/settings.php
if (Settings::get('allowed_subnets_enabled'))
{
$this->form->input('allowed_subnets_default_count')
->label('Default allowed subnets count')
->help(help::hint('allowed_subnets_default_count'))
->rules('required_with_zero|valid_digit')
->value(Settings::get('allowed_subnets_default_count'));
$this->form->input('allowed_subnets_update_interval')
->label('Interval of update')
->help(help::hint('allowed_subnets_update_interval'))
application/controllers/transfers.php
$order_by = 'id';
if (strtolower($order_by_direction) != 'desc')
$order_by_direction = 'desc';
$order_by_direction = 'asc';
// there are two groups of transfers
$arr_groups[Transfer_Model::OUTER_TRANSFERS] = __('Outer transfers');
application/i18n/cs_CZ/texts.php
'deduction of device repayments' => 'Stržení splátek zařízení',
'deduction of entrance fees' => 'Stržení vstupních příspěvků',
'default' => 'Výchozí',
'default allowed subnets count' => 'Výchozí počet povolených podsítí',
'default approval template' => 'Výchozí hlasovací šablona',
'default approval template for "proposals to association"' => 'Výchozí hlasovací šablona pro "návrhy na sdružení"',
'default approval template for "support requests"' => 'Výchozí hlasovací šablona pro "požadavky na podporu"',
application/libraries/forge/Form_Input.php
}
}
/**
* Validate required that works for zero number.
*/
protected function rule_required_with_zero()
{
if ($this->value == FALSE && $this->value !== '0')
{
$this->errors['required'] = TRUE;
}
}
/**
* Validate length.
*/
application/vendors/mpdf/CHANGELOG.txt
===========================
mPDF 5.6
20/01/2013
===========================
Files changed
-------------
mpdf.php
config.php
includes/functions.php
classes/meter.php
classes/directw.php
config.php changes
------------------
$this->allowedCSStags - added HTML5 tags + textcircle AND
$this->outerblocktags - added HTML5 tags
$this->defaultCSS - added default CSS properties
New features / Improvements
---------------------------
CSS support added for for min-height, min-width, max-height and max-width in <img>
Images embedded in CSS
<img src="data:image/gif;base64,...."> improved to make it more robust, and
background: url(data:image... now added to work
HTML5 tags supported
- as generic block elements: <article><aside><details><figure><figcaption><footer><header><hgroup><nav><section><summary>
- as in-line elements: <mark><time><meter><progress>
- <mark> has a default CSS set in config.php to yellow highlight
- <meter> and <progress> support attributes as for HTML5
- custom appearances for <meter> and <progress> can be made by editing classes/meter.php file
- <meter> and <progress> suppress text inside the tags
Textcircle/Circular
font: "auto" added: automatically sizes text to fill semicircle (if both set) or full circle (if only one set)
NB for this AND ALL CSS on <textcircle>: does not inherit CSS styles
attribute: divider="[characters including HTML entities]" added
<textcircle r="30mm" top-text="Text Circular Text Circular" bottom-text="Text Circular Text Circular"
divider="&nbsp;&bull;&nbsp;" style="font-size: auto" />
&raquo; &rsquo; &sbquo; &bdquo; are now included in "orphan"-management at the end of lines
Improved CJK line wrapping (if CJK character at end of line, breaks there rather than previous wordspace)
NB mPDF 5.5 added support for <fieldset> and <legend> (omitted from ChangeLog)
Bug fixes
---------
- embedded fonts: Panose string incorrectly output as decimals - changed to hexadecimal
Only a problem in limited circumstances.
*****Need to delete all ttfontdata/ files in order for fix to have effect.
- <textCircle> background white even when set to none/transparent
- border="0" causing mPDF to add border to table CELLS as well as table
- iteration counter in THEAD crashed in some circumstances
- CSS color now supports spaces in the rgb() format e.g. border: 1px solid rgb(170, 170, 170);
- CJK not working in table following changes made in v5.4
- images fixed to work with Google Chart API (now mPDF does not urldecode the query part of the src)
- CSS <style> within HTML page crashed if CSS is too large (? > 32Kb)
- SVG image nested int eht HTML failed to show if code too large (? > 32Kb)
- cyrillic character p &#1088; at end of table cell caused cell height to be incorrectly calculated
===========================
mPDF 5.5
02/03/2012
===========================
Files changed
-------------
mpdf.php
classes/ttfontsuni.php
classes/svg.php
classes/tocontents.php
config.php
config_fonts.php
utils/font_collections.php
utils/font_coverage.php
utils/font_dump.php
Files added
-----------
classes/ttfontsuni_analysis.php
config.php changes
------------------
To avoid just the border/background-color of the (empty) end of a block being moved on to next page (</div></div>)
$this->margBuffer = 0; // Allow an (empty) end of block to extend beyond the bottom margin by this amount (mm)
config_fonts.php changes
------------------------
Added to (arabic) fonts to allow "use non-mapped Arabic Glyphs" e.g. for Pashto
'unAGlyphs' => true,
Arabic text
-----------
Arabic text (RTL) rewritten with improved support for Pashto/Sindhi/Urdu/Kurdish
Presentation forms added:
U+0649, U+0681, U+0682, U+0685, U+069A-U+069E, U+06A0, U+06A2, U+06A3, U+06A5, U+06AB-U+06AE,
U+06B0-U+06B4, U+06B5-U+06B9, U+06BB, U+06BC, U+06BE, U+06BF, U+06C0, U+06CD, U+06CE, U+06D1, U+06D3, U+0678
Joining improved:
U+0672, U+0675, U+0676, U+0677, U+0679-U+067D, U+067F, U+0680, U+0683, U+0684, U+0687, U+0687, U+0688-U+0692,
U+0694, U+0695, U+0697, U+0699, U+068F, U+06A1, U+06A4, U+06A6, U+06A7, U+06A8, U+06AA, U+06BA, U+06C2-U+06CB, U+06CF
Note -
Some characters in Pashto/Sindhi/Urdu/Kurdish do not have Unicode values for the final/initial/medial forms of the characters.
However, some fonts include these characters "un-mapped" to Unicode (including XB Zar and XB Riyaz, which are bundled with mPDF).
'unAGlyphs' => true,
added to the config_fonts.php file for appropriate fonts will
This requires the font file to include a Format 2.0 POST table which references the glyphs as e.g. uni067C.med or uni067C.medi:
e.g. XB Riyaz, XB Zar, Arabic Typesetting (MS), Arial (MS)
NB If you want to know if a font file is suitable, you can open a .ttf file in a text editor and search for "uni067C.med"
- if it exists, it may work!
Using "unAGlyphs" forces subsetting of fonts, and will not work with SIP/SMP fonts (using characters beyond the Unicode BMP Plane).
mPDF maps these characters to part of the Private Use Area allocated by Unicode U+F500-F7FF. This could interfere with correct use
if the font already utilises these codes (unlikely).
mPDF now deletes U+200C,U+200D,U+200E,U+200F zero-widthjoiner/non-joiner, LTR and RTL marks so they will not appear
even though some fonts contain glyphs for these characters.
Other New features / Improvements
---------------------------------
Avoid just the border/background-color of the (empty) end of a block being moved on to next page (</div></div>)
using configurable variable: $this->margBuffer;
The TTFontsUni class contained a long function (extractcoreinfo) which is not used routinely in mPDF
This has been moved to a new file: classes/ttfontsuni_analysis.php
The 3 utility scripts have been updated to use the new extended class:
- utils/font_collections.php
- utils/font_coverage.php
- utils/font_dump.php
Bug fixes
---------
- Border & background when closing 2 blocks (e.g. </div></div>) incorrectly being moved to next page because incorrectly
calculating how much space required
- Fixed/Absolute-positioned elements not inheriting letter-spacing style
- Rotated cell - error if text-rotate set on a table cell, but no text content in cell
- SVG images, text-anchor not working
- Nested table - not resetting cell style (font, color etc) after nested table, if text follows immediately
- Nested table - font-size 70% set in extenal style sheet; if repeated nested tables, sets 70% of 70% etc etc
- SVG setting font-size as percent on successive <text> elements gives progressively smaller text
- mPDF will check if magic_quotes_runtime set ON even >= PHP 5.3 (will now cause an error message)
- not resetting after 2 nested tags of same type e.g. <b><b>bold</b></b> still bold
- When using charset_in other than utf-8, HTML Footers using tags e.g. <htmlpageheader> do not decode correctly
- ToC if nested > 3 levels, line spacing reduces and starts to overlap
================
mPDF 5.7.2
15/05/2014
================
===========================
mPDF 5.4
14/02/2012
===========================
Files changed
Files changed (from 5.7.1)
-------------
mpdf.php
config.php
compress.php
classes/ttfontsuni.php
classes/barcode.php
classes/indic.php
classes/cssmgr.php
classes/svg.php
examples/show_code.php ----- SECURITY RISK**
examples/example49_changelog.php
examples/example57_new_mPDF_v5-3_active_forms_b (replace example57_new_mPDF_v5-3_active_forms)
includes/out.php
mpdfi/fpdi_pdf_parser.php
Files added
-----------
classes/bmp.php
classes/directw.php
classes/form.php
classes/grad.php
classes/tocontents.php
classes/wmf.php
examples/example58_new_mPDF_v5-4_features
config.php changes
------------------
Edited: $this->allowedCSStags, $this->innerblocktags, $this->defaultCSS; (CAPTION added in each case)
Moved: Numerous $form_.. variables are now in /classes/form.php
New config variables
--------------------
$this->bookmarkStyles = array();
$this->cacheTables = true;
New methods
-----------
function CircularText()
function SetVisibility()
New/Extended CSS
----------------
box-shadow (block elements - does NOT support "inset")
text-shadow (all text elements - does NOT support "blur")
visibility: visible|hidden|printonly|screenonly (block-level elements and images IMG only)
text-transform: capitalize|uppercase|lowercase (extended to support TD/TH)
tr|td|th:nth-child(odd|even|2n+1)
color, strikethrough, underline and background-color (extended to support rotated TD/TH)
underline and strike-through (extended to support TD/TH)
underline (line colour) (extended to work correctly in watermark)
page-break-after: left|right|always (block elements and tables)
NB respects $mpdf->restoreBlockPagebreaks = true; i.e. will make pagebreak act like formfeed
background[-color]: extended to support rgba|cmyka|cmyk|hsla|hsl|spot
border(extended to support inline elements)
New HTML
--------
<caption>
<textcircle />
New features / Improvements
---------------------------
Tables - Zebra Stripes
Tables: overlapping rowspans (partially) supported
Tables - Disk caching
Using progress bars (or $showStats) now reports 'real' memory usage i.e. get_memory_usage(true)
Support for query string in the URLs for external stylesheets e.g. @import url("style.css?ltcyy7");
Table caption partially supported
CircularText
BookMark styling
Spread tables i.e. can split table (columns) across several pages width.
Can use chelvetica, ctimes and ccourier to specify core fonts in a non-core font document
Spread tables i.e. can split table (columns) across several pages width.
{colsum} in <tfoot> cell will insert a column total per page.
SVG embedded as island in HTML supported
Active Forms
textarea and input (text types) now accept javascript as:
onKeystroke, onValidate, onCalculate and onFormat
onChange is depracated but works as onCalculate (for textarea and input)
(PS Select still accepts onChange cf. 5.3.37)
Ledger and Tabloid added as page formats recognised. NB Ledger is same as tabloid but landscape. In mPDF, both give the same size (portrait)
so need to add -L e.g. Ledger-L for landscape.
Internal script changes
-----------------------
Changed this->k to _MPDFK throughout all scripts
Changes to color (packed binary data in string rather than array) to reduce memory usage esp in tables
Internal variables Removed
$usetableheader;
$tableheadernrows;
$tablefooternrows;
vars $ChangePage, $p_bottom_border, $img_margin_top(+) $issetcolor + other similar removed
Removed a whole load of // comments
Updates to remove some more Warning Notices (not all marked in text)
Border set on TR - changed so set on each cell, rather than retrospectively at end of TR
All references to table['text'] removed as not needed - uses ['textbuffer'] instead
OpenTag(TD) changes to reduce memory usage with tables
Includes different method to set a default timezone
fn _smallCaps does not need (undefined) $space
this->chrs and this->ords replaced by chr() and ord()
Headers in out.php updated to match those used in Output()
Change to SetFont() to improve performance time
Change to GetStringWidth() to improve performance time
Corrected copying of Glyphs 0,1,2, to all subset fonts (non-SMP/SIP), and only setting 32->127 in subset
Subset fonts (non-SMP/SIP) have additionally Unicode CMap tables (0,0,4 and 0,3,4) as well as Microsoft (3,1,4)
Subset fonts (SMP/SIP) have CMap tables (1,0,6 and 3,0,4) - rather than 1,0,6 and 3,0,6
Subset fonts (SMP/SIP) have 'name' table changed to give 1,0 and 3,0. As it is a symbol font (not Unicode encoded) :
needs to have a name entry in 3,0 (e.g. symbol) - original font will have 3,1 (i.e. Unicode)
Automatically checks for HTML code length > 100000 characters and gives error warning if
PHP < 5.2.0 (as not configurable) or increases pcre.backtrack_limit if PHP < 5.3.7
Removed/Depracated
------------------
function UseTableHeader($opt=true) fn removed / depracated
function UsePRE($opt=true) removed
$attr['REPEAT_HEADER'] == true CSS removed / depracated
$this->usepre=true; removed / depracated as never needed - always respects PRE whitespace
ToC: NB Values can no longer be set directly e.g. as in example
$mpdf->TOCheader = array(); // array as for setting header/footer
$mpdf->TOCfooter = array(); // array as for setting header/footer
$mpdf->TOCpreHTML = '<h2>Contents - Portrait</h2>'; // HTML text to appear before table of contents
$mpdf->TOCpostHTML = ''; // HTML text to appear after table of contents
$mpdf->TOCbookmarkText = 'Content list'; // Text as it will appear in the Bookmarks (leave blank for none)
Need to use TOCpagebreak either direct (or array version) or as HTML
OR if absolutley necessary, could use:
$mpdf->tocontents->TOCheader = array(); // array as for setting header/footer
$mpdf->tocontents->TOCfooter = array(); // array as for setting header/footer
$mpdf->tocontents->TOCpreHTML = '<h2>Contents - Portrait</h2>'; // HTML text to appear before table of contents
$mpdf->tocontents->TOCpostHTML = ''; // HTML text to appear after table of contents
$mpdf->tocontents->TOCbookmarkText = 'Content list'; // Text as it will appear in the Bookmarks (leave blank for none)
Further Details
===============
CSS border on inline elements
-----------------------------
Support for CSS border (and variants) on inline elements e.g. <span style="border-bottom: 1px dashed #000000;">
Border styles solid|dotted|dashed|double only are supported. Border radius not supported.
Nested inline elements will have repeat left|right borders on the nested content (unlike browsers)
Tables - Zebra Stripes
----------------------
TABLE - striped rows cf. http://dev.opera.com/articles/view/zebra-striping-tables-with-css3/
tr:nth-child(odd) { background-color: #99ff99; }
thead tr:nth-child(3n+2) { background-color: #FFBBFF; }
td:nth-child(2n+1) { background-color: #BBBBFF; }
table.zebraTable td:nth-child(2n+1) { background-color: #BBBBFF; }
table.zebraTable th:nth-child(2n+1) { background-color: #BBBBFF; }
NB mPDF does NOT correctly apply specificity to all CSS
table.zebra tbody tr:nth-child(2n+1) td { background-color: #FFFFBB; }
table.zebra tbody td:nth-child(odd) { background-color: #BBBBFF; }
should make every odd row yellow, and every odd coloumn blue, but with the row/yellow overriding the column/blue.
In mPDF the td:nth-child(odd) trumps the plain td, so the column colour wins out. You can force the effect you want by using
table.zebra tbody tr:nth-child(2n+1) td:nth-child(1n+0) { background-color: #FFFFBB; }
(The :nth-child(1n+0) selector just selects every td cell.)
Tables - Disk caching
---------------------
TABLES: using disk caching
// Using disk to cache table data can reduce memory usage dramatically, but at a cost of increased
// executon time and disk access (read and write)
$this->cacheTables = true;
NB $this->packTableData will be overridden to => true; // required for cacheTables
$this->simpleTables will be overridden to => false; // Cannot co-exist with cacheTables
Table caption
-------------
Must come immediately after <table...>
CSS caption-side and HTML align attribute of top|bottom supported (not attribute left|right)
Handled as a separate block element brought outside the table, so:
CSS will not cascade correctly on the table
width of caption block is that of page or of the block element containing the table
so alignment will be to the page-width not the table width
if table page-break-after: always, the caption will follow the pagebreak.
This does work:
<style>
.tablecaption { caption-side: bottom; text-align: left; font-weight: bold; color: green; }
</style>
...
<table>
<caption class="tablecaption">Caption title here</caption>
<tbody>
CSS visibility: printonly, screenonly
-------------------------------------
Roughly based on CSS
Works on Block elements P, DIV etc, or Image
Cannot nest / layer.
Inner blocks/image with set visibility are ignored if already set on enclosing block element.
(Block element) does not work inside table (image does)
So 'visible' does nothing but is set as default
(NB Changes output to PDF version 1.5)
Incompatible with PDFA / PDFX
'visibility'
Value: visible | hidden | (collapse | inherit)
Initial: visible
Applies to: all elements
Inherited: yes
The 'visibility' property specifies whether the boxes generated by an element are rendered.
Invisible boxes still affect layout (set the 'display' property to 'none' to suppress box generation altogether).
Values have the following meanings:
visible
The generated box is visible.
hidden
The generated box is invisible (fully transparent, nothing is drawn), but still affects layout.
Furthermore, descendants of the element will be visible if they have 'visibility: visible'.
collapse | inherit
NOT supported in mPDF
CUSTOM:
printonly | screenonly
Added VISIBILITY function
$mpdf->SetVisibility('screenonly'); or 'printonly' 'visible' or 'hidden'
(NB Changes output to PDF version 1.5)
Incompatible with PDFA / PDFX
CircularText
------------
function CircularText($x, $y, $r, $text, $align='top', $kerning=120, $fontwidth=100) {
x: abscissa of center
y: ordinate of center
r: radius of circle
text: text to be printed
align: text alignment: top or bottom. Default value: top
kerning: spacing between letters in percentage. Default value: 120. Zero is not allowed.
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff