浏览代码

Merge branch 'master' of biuro.biall-net.pl:plabudda/se

a.binder 11 年之前
父节点
当前提交
206c4f457e

+ 1 - 2
SE/index-ajax.php

@@ -9,8 +9,7 @@ define('APP_PATH_CONFIG', APP_PATH_ROOT . DS . 'config');
 //session_save_path("./tmp") ;
 session_start();
 
-//date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions
-date_default_timezone_set('UTC');// PHP 5 >= 5.1.0 required by date functions //needed for system working sync!
+date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions
 
 error_reporting(E_ALL);
 ini_set('error_reporting', E_ALL);

+ 1 - 2
SE/index.php

@@ -10,8 +10,7 @@ define('APP_PATH_SCHEMA', APP_PATH_ROOT . DS . 'schema');
 //session_save_path("./tmp") ;
 session_start();
 
-//date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions
-date_default_timezone_set('UTC');// PHP 5 >= 5.1.0 required by date functions //needed for system working sync!
+date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions
 
 $errorReportingLevel = E_ALL & ~E_NOTICE;
 error_reporting($errorReportingLevel);

+ 12 - 21
SE/procesy/ajax.php

@@ -1,5 +1,7 @@
 <?php
 
+Lib::loadClass('DB_Image');
+
 if (!class_exists('Lib')) die('404');
 
 function ajax_get_subtree() {
@@ -8,7 +10,9 @@ function ajax_get_subtree() {
 	$id = V::get('id', '', $_GET);
 	$tbl = V::get('tbl', '', $_GET);
 
-	$tree_filter = get_filter_for_table($tbl);
+	Lib::loadClass('FilterFactory');
+	$tree_filter = FilterFactory::build($tbl);
+	$tree_filter->setArgs($_GET);
 
 	$clbk = 'tree_callback__show_item_from_'.$tbl;
 	if (!function_exists($clbk)) {
@@ -59,8 +63,6 @@ function ajax_add_image() {
 	$errors = array();
 	$msgs = array();
 
-	Lib::loadClass('DB_Image');
-
 	// check remote id
 	if ($remote_id <= 0) {
 		echo'<p>';
@@ -72,8 +74,7 @@ function ajax_add_image() {
 	}
 
 	// check remote table
-	$remote_tables = DB_Image::conf_get('remote_tables');
-	if (!in_array($remote_table, $remote_tables)) {
+	if (!DB_Image::tableIsAllowed($remote_table)) {
 		$errors[] = "Error table not allowed to add image";
 	}
 
@@ -98,7 +99,7 @@ function ajax_add_image() {
 		}
 
 		if (empty($errors)) {
-			$affected = DB_Image::delete_image($req['ID'], $req['REMOTE_TABLE'], $req['REMOTE_ID']);
+			$affected = DB_Image::deleteImage($req['ID'], $req['REMOTE_TABLE'], $req['REMOTE_ID']);
 			if ($affected == 1) {
 				$msgs[] = '<p>'."Usunieto zdjecie ID=".$req['ID'].'</p>';
 			} else {
@@ -112,7 +113,7 @@ function ajax_add_image() {
 		//echo '<p>Please select a file</p>';
 	}
 	else {
-		$errors = DB_Image::upload_image($remote_table, $remote_id, $_FILES['userfile']);
+		$errors = DB_Image::uploadImage($remote_table, $remote_id, $_FILES['userfile']);
 		// give praise and thanks to the php gods
 		if (empty($errors)) {
 			$msgs[] = '<p>Thank you for submitting</p>';
@@ -173,7 +174,7 @@ function ajax_add_image() {
 
 
 // TODO: show images, mv to function {
-	$images = DB_Image::get_images($thiss->DETECT_TABLE_NAME, $remote_id);
+	$images = DB_Image::getImages($thiss->DETECT_TABLE_NAME, $remote_id);
 
 	if (empty($images)) {
 		echo'<p class="err">'."Brak obrazkow".'</p>';
@@ -431,8 +432,6 @@ function ajax_show_images() {
 	$thiss = new stdClass();
 	$thiss->DETECT_TABLE_NAME = $remote_table;
 
-	Lib::loadClass('DB_Image');
-
 	// check remote id
 	if ($remote_id <= 0) {
 		header('HTTP/1.1 400: Bad Request');
@@ -448,16 +447,8 @@ function ajax_show_images() {
 		exit;
 	}
 
-	$db = DB::getDB();
-	$sql = "select `ID`, `TYPE`, `SIZE`, `DEST`
-		from `".DB_Image::conf_get_table_name()."`
-		where
-			`REMOTE_ID`='{$remote_id}'
-			and `REMOTE_TABLE`='{$remote_table}'
-	";
-
-	$res = $db->query($sql);
-	if (!$db->num_rows($res)) {
+	$images = DB_Image::getImages($remote_table, $remote_id);
+	if (!$images) {
 		header('HTTP/1.1 400: Bad Request');
 		header('Warning: images not found in db L.' . __LINE__);
 		exit;
@@ -465,7 +456,7 @@ function ajax_show_images() {
 
 	echo'<p>'."Zdjecia dla rekordu <b>{$remote_id}</b> z tabeli {$remote_table}".'</p>';
 
-	while ($r = $db->fetch($res)) {
+	foreach ($images as $r) {
 		$src = "?function_init=fun_SHOW_IMAGE&image_id={$r->ID}";
 		echo'<img src="'.$src.'" alt="'.$r->TYPE.'" />';
 	}

+ 35 - 62
SE/procesy/index.php

@@ -43,93 +43,66 @@ function fun_SHOW_EXTERNAL_IMAGE() {
 	$remote_table = V::get('tbl', '', $_REQUEST);
 	$remote_id = V::get('id', '', $_REQUEST, 'int');
 	$number = V::get('number', '', $_REQUEST, 'int');
-	$image_resize = V::get('resize', '', $_REQUEST);
+	$imageResize = V::get('resize', '', $_REQUEST);
+	$DBG = (V::get('DBG', 0, $_REQUEST, 'int') > 0);
 
 	Lib::loadClass('DB_Image');
 
-	// check remote id
 	if ($remote_id <= 0) {
 		header('HTTP/1.1 400: Bad Request');
 		header('Warning: wrong ID L.' . __LINE__);
 		exit;
 	}
 
-	// check remote table
-	$remote_tables = DB_Image::conf_get('remote_tables');
-	if (!in_array($remote_table, $remote_tables)) {
+	if (!DB_Image::tableIsAllowed($remote_table)) {
 		header('HTTP/1.1 400: Bad Request');
 		header('Warning: table not allowed L.' . __LINE__);
 		exit;
 	}
 
-	$db = DB::getDB();
-	$sql = "select `ID`, `TYPE`, `SIZE`, `IMAGE`, `WIDTH`, `HEIGHT`, UNIX_TIMESTAMP(`A_CREATE_DATE`) as A_CREATE_DATE
-		from `".DB_Image::conf_get_table_name()."`
-		where
-			`REMOTE_ID`='".$remote_id."'
-			and `REMOTE_TABLE`='".$remote_table."'
-		order by `ID` asc
-		limit 1 offset ".$number."
-	";
-
-	$res = $db->query($sql);
-	if (!$db->num_rows($res)) {
+	$image_row = DB_Image::getImage($remote_table, $remote_id, $number);
+	if (!$image_row) {
 		header('HTTP/1.1 400: Bad Request');
-		header('Warning: images not found in db L.' . __LINE__);
+		header('Warning: image not found in db L.' . __LINE__);
 		exit;
 	}
 
-	if ($image_row = $db->fetch( $res )) {
-		$etag = md5($image_row->ID . $image_row->A_CREATE_DATE);
-		if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $image_row->A_CREATE_DATE
-			|| trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
-			header("HTTP/1.1 304 Not Modified");
-			exit;
-		}
-		$expire_date = mktime(0, 0, 0, date('m') + 3, date('d'), date('Y'));
-
-		if ($image_resize) {
-			list($resize_w, $resize_h) = explode('x', $image_resize, 2);
-			$resize_w = intval($resize_w); $resize_h = intval($resize_h);
-			if ($resize_w > 0 && $resize_h > 0) {
-				$im = imagecreatefromstring( $image_row->IMAGE );
-				$image_resized = DB_Image::resize_image_from_data($im, $resize_w, $resize_h);
-
-				header("Content-type: ".$image_row->TYPE);
-				//header("Cache-control: public");
-				header("Cache-control: public");
-				header("Pragma: public");// default 'no-cache'
-				header("Etag: ".$etag);
-				header("Expires: " . gmdate("D, d M Y H:i:s", $expire_date) . " GMT");
-				header("Last-Modified: " . gmdate("D, d M Y H:i:s", $image_row->A_CREATE_DATE) . " GMT");
-				if ($image_row->TYPE == 'image/png') {
-					imagepng($image_resized);
-				} else if ($image_row->TYPE == 'image/jpeg' || $image_row->TYPE == 'image/jpg') {
-					imagejpeg($image_resized);
-				} else if ($image_row->TYPE == 'image/gif') {
-					imagegif($image_resized);
-				}
-			} else {
-				echo'ERROR wrong param resize (WxH)';
-			}
+	$etag = md5($image_row->ID . $image_row->A_CREATE_DATE_TS);
+	if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $image_row->A_CREATE_DATE_TS
+		|| trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
+		header("HTTP/1.1 304 Not Modified");
+		exit;
+	}
+	$expire_date = mktime(0, 0, 0, date('m') + 3, date('d'), date('Y'));
+
+	$maxWidth = 0;
+	$maxHeight = 0;
+	if ($imageResize) {
+		list($maxWidth, $maxHeight) = explode('x', $imageResize, 2);
+		$maxWidth = intval($maxWidth);
+		$maxHeight = intval($maxHeight);
+		if ($maxWidth <= 0 || $maxHeight <= 0) {
+			header('HTTP/1.1 400: Bad Request');
+			echo'ERROR wrong param resize (WxH)';
 			exit;
 		}
+	}
 
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">';print_r($image_row);echo'</pre>';
-		//header("Content-type: ".$image_row->TYPE);
-		header("Content-type: ".$image_row->TYPE);
+	if (!$DBG) {
+		header("Content-type: {$image_row->TYPE}");
 		header("Cache-control: public");
 		header("Pragma: public");// default 'no-cache'
-		header("Etag: ".$etag);
-		header("Content-length: ".$image_row->SIZE);
+		header("Etag: {$etag}");
+		if (!$imageResize) {
+			header("Content-length: {$image_row->SIZE}");
+		}
 		header("Expires: " . gmdate("D, d M Y H:i:s", $expire_date) . " GMT");
-		header("Last-Modified: " . gmdate("D, d M Y H:i:s", $image_row->A_CREATE_DATE) . " GMT");
-		//echo stripslashes($image_row->IMAGE);
-		print $image_row->IMAGE;
-		//file_put_contents('/home/pl/projekty/kyoritsu.pl/src/1.jpg', $image_row->IMAGE);
+		header("Last-Modified: " . gmdate("D, d M Y H:i:s", $image_row->A_CREATE_DATE_TS) . " GMT");
+	}
+	if ($imageResize) {
+		print DB_Image::resizeImageFromBlob($image_row->IMAGE, $image_row->TYPE, $maxWidth, $maxHeight);
 	} else {
-		header('HTTP/1.1 400: Bad Request');
-		header('Warning: image not found in db L.' . __LINE__);
+		print $image_row->IMAGE;
 	}
 	exit;
 }

+ 5 - 2
SE/procesy/proces.php

@@ -92,8 +92,10 @@ function task_CRM_PROCES() {
 	{// TREE - Filter
 		$tbl = 'CRM_PROCES';
 
-		$tree_procesy_filter = get_filter_for_table( $tbl );
-		$tree_procesy_filter->set_trash( 'filtr_id', -1 );
+		Lib::loadClass('FilterFactory');
+		$tree_procesy_filter = FilterFactory::build($tbl);
+		$tree_procesy_filter->setArgs($_GET);
+		$tree_procesy_filter->set_trash('filtr_id', -1);
 
 		{// zapisz stan - ajax function to save filters stan and opened tree nodes, etc.
 			$filtr_ses_key = $tree_procesy_filter->_key;
@@ -199,6 +201,7 @@ echo'<div id="tree"></div>';
 		$tree->set_param('search_id', $tree_procesy_filter->get_arg('filtr_search_id'));
 		$tree->set_param('ProcesTblId', ProcesHelper::getZasobTableID('CRM_PROCES'));
 		$tree->set_param('ZasobTblId', ProcesHelper::getZasobTableID('CRM_LISTA_ZASOBOW'));
+		$tree->set_param('WskaznikTblId', ProcesHelper::getZasobTableID('CRM_WSKAZNIK'));
 
 		$tblPytaniaId = ProcesHelper::getZasobTableID('CRM_TESTY_PYTANIA');
 		if ($tblPytaniaId > 0) {

+ 4 - 2
SE/procesy/zasob.php

@@ -93,8 +93,10 @@ function task_CRM_LISTA_ZASOBOW() {
 	{// TREE - Filter
 		$tbl = 'CRM_LISTA_ZASOBOW';
 
-		$tree_zasoby_filter = get_filter_for_table( $tbl );
-		$tree_zasoby_filter->set_trash( 'filtr_id', -1 );
+		Lib::loadClass('FilterFactory');
+		$tree_zasoby_filter = FilterFactory::build($tbl);
+		$tree_zasoby_filter->setArgs($_GET);
+		$tree_zasoby_filter->set_trash('filtr_id', -1);
 
 		{// zapisz stan - ajax function to save filters stan and opened tree nodes, etc.
 			$filtr_ses_key = $tree_zasoby_filter->_key;

+ 109 - 330
SE/procesy5.php

@@ -38,6 +38,8 @@ Lib::loadClass('S');
 Lib::loadClass('ProcesHelper');
 Lib::loadClass('Tree');
 Lib::loadClass('TreeHelper');
+Lib::loadClass('DB_Image');
+Lib::loadClass('TreeSortChildren');
 
 //   ==========  Task functions  ==============
 require_once APP_PATH_ROOT . DS . 'procesy' . DS . 'legacy.php';
@@ -193,6 +195,42 @@ jQuery(document).ready(function(){
 	});
 });
 	</script>
+	<link rel="stylesheet" href="stuff/jquery.selectize/css/selectize.bootstrap2.css" type="text/css" />
+	<script src="stuff/jquery.selectize/js/standalone/selectize.min.js"></script>
+	<style type="text/css">
+.typepsecial .selectize-input { width:366px; padding:4px 6px; }
+.typepsecial .selectize-control::before {
+	-moz-transition: opacity 0.2s;
+	-webkit-transition: opacity 0.2s;
+	transition: opacity 0.2s;
+	content: ' ';
+	z-index: 2;
+	position: absolute;
+	display: block;
+	top: 12px;
+	right: 34px;
+	width: 16px;
+	height: 16px;
+	background: url(stuff/i/loading.gif);
+	background-size: 16px 16px;
+	opacity: 0;
+}
+.typepsecial .selectize-control.loading::before {
+	opacity: 0.4;
+}
+.typepsecial .selectize-control.single .selectize-input {
+	color: #333;
+	text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
+	background-color: #fff;
+	background-image: none;
+	background-repeat: none;
+	border-color: #ccc;
+	filter: none;
+	-webkit-box-shadow: none;
+	-moz-box-shadow: none;
+	box-shadow: none;
+}
+	</style>
 	<?php
 		lay_procesy_css();
 		App::show_head_css();
@@ -259,111 +297,25 @@ function SESSION_USER_PARAMS() {
 	}
 }
 
-
 function SORT_PRIO_ZASOB() {
-	SORT_PRIO( 'CRM_LISTA_ZASOBOW', 'PARENT_ID' );
+	$id = V::get('arg1', '', $_GET, 'int');
+	$sort_prio_dir = V::get('arg1_val', '', $_GET);
+	TreeSortChildren::sortPrio($id, 'CRM_LISTA_ZASOBOW', 'PARENT_ID', $sort_prio_dir);
 }
 
-
 function SORT_PRIO_WSKAZNIK() {
-	SORT_PRIO( 'CRM_WSKAZNIK', 'ID_PROCES' );
+	$id = V::get('arg1', '', $_GET, 'int');
+	$sort_prio_dir = V::get('arg1_val', '', $_GET);
+	TreeSortChildren::sortPrio($id, 'CRM_WSKAZNIK', 'ID_PROCES', $sort_prio_dir);
 }
 
-
 function SORT_PRIO_PROCES() {
+	$id = V::get('arg1', '', $_GET, 'int');
 	//$_GET['arg1_val'] = ($_GET['arg1_val'] == 'up')? 'dw' : 'up';// procesy w odwrotnej kolejnosci, w SQL order by SORT_PRIO DESC
-	SORT_PRIO( 'CRM_PROCES', 'PARENT_ID' );
+	$sort_prio_dir = V::get('arg1_val', '', $_GET);
+	TreeSortChildren::sortPrio($id, 'CRM_PROCES', 'PARENT_ID', $sort_prio_dir);
 }
 
-
-function SORT_PRIO( $table, $parent_id_field ) {
-	if (!isset($_GET['arg1']) || !isset($_GET['arg1_val'])) {
-		return;
-	} else if (($id = intval($_GET['arg1'])) > 0) {
-		$sort_prio_dir = $_GET['arg1_val'];
-		//echo'TODO: wskaznik id ('.$id.') -> '.$sort_prio_dir;
-		$sql = "select
-				w.`ID`
-				, w.`SORT_PRIO`
-			from `".$table."` as w0
-				left join `".$table."` as w on(w.`".$parent_id_field."`=w0.`".$parent_id_field."`)
-			where
-				w0.`ID`='".$id."'
-			order by w.`SORT_PRIO` asc, w.`ID` asc
-		";
-		$res = DB::query( $sql );
-		$wsk = array();
-		$wsk_order = array();
-		$sort_prio = 0;
-		while ($r = DB::fetch( $res )) {
-			$wsk [$r->ID] = $sort_prio;//$r->SORT_PRIO;
-			$wsk_order [$sort_prio]= $r->ID;
-			$sort_prio += 1;
-		}
-		if (empty($wsk)) return;
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">wsk ';print_r($wsk);echo'</pre>';
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">wsk_order ';print_r($wsk_order);echo'</pre>';
-		$wsk_new = array();
-		if ($sort_prio_dir == 'up') {// wskaznik $wsk_id 'w gore' (zmniejsz sort_prio)
-			$old_wsk_id = $wsk[ $id ];
-			if ($old_wsk_id == 0) return;
-			//echo'zamien "'.$id.'" na "'.$wsk_order[ $wsk[ $id ] - 1 ].'"';
-			$tmp = $wsk_order[ $wsk[ $id ] ];
-			$wsk_order[ $wsk[ $id ] ] = $wsk_order[ $wsk[ $id ] - 1 ];
-			$wsk_order[ $wsk[ $id ] - 1 ] = $tmp;
-		} else if ($sort_prio_dir == 'upup') {// wskaznik $wsk_id 'w gore' (zmniejsz sort_prio)
-			$old_wsk_id = $wsk[ $id ];
-			if ($old_wsk_id == 0) return;
-			$tmp = $wsk_order[ $wsk[ $id ] ];
-			$tmp1 = $wsk_order[ $wsk[ $id ] -1 ];
-			$tmp2 = $wsk_order[ $wsk[ $id ] -2 ];
-			$tmp3 = $wsk_order[ $wsk[ $id ] -3 ];
-			$tmp4 = $wsk_order[ $wsk[ $id ] -4 ];
-			$tmp5 = $wsk_order[ $wsk[ $id ] -5 ];
-			$tmp6 = $wsk_order[ $wsk[ $id ] -6 ];
-			$wsk_order[ $wsk[ $id ] ] = $tmp1;
-			$wsk_order[ $wsk[ $id ] - 1 ] = $tmp2;
-			$wsk_order[ $wsk[ $id ] - 2 ] = $tmp3;
-			$wsk_order[ $wsk[ $id ] - 3 ] = $tmp4;
-			$wsk_order[ $wsk[ $id ] - 4 ] = $tmp5;
-			$wsk_order[ $wsk[ $id ] - 5 ] = $tmp6;
-			$wsk_order[ $wsk[ $id ] - 6 ] = $tmp;
-		} else if ($sort_prio_dir == 'downdown') {// wskaznik $wsk_id 'w gore' (zmniejsz sort_prio)
-			$old_wsk_id = $wsk[ $id ];
-			if ($old_wsk_id == 0) return;
-			$tmp = $wsk_order[ $wsk[ $id ] ];
-			$tmp1 = $wsk_order[ $wsk[ $id ] +1 ];
-			$tmp2 = $wsk_order[ $wsk[ $id ] +2 ];
-			$tmp3 = $wsk_order[ $wsk[ $id ] +3 ];
-			$tmp4 = $wsk_order[ $wsk[ $id ] +4 ];
-			$tmp5 = $wsk_order[ $wsk[ $id ] +5 ];
-			$tmp6 = $wsk_order[ $wsk[ $id ] +6 ];
-			$wsk_order[ $wsk[ $id ] ] = $tmp1;
-			$wsk_order[ $wsk[ $id ] + 1 ] = $tmp2;
-			$wsk_order[ $wsk[ $id ] + 2 ] = $tmp3;
-			$wsk_order[ $wsk[ $id ] + 3 ] = $tmp4;
-			$wsk_order[ $wsk[ $id ] + 4 ] = $tmp5;
-			$wsk_order[ $wsk[ $id ] + 5 ] = $tmp6;
-			$wsk_order[ $wsk[ $id ] + 6 ] = $tmp;
-		} else {// wskaznik $wsk_id 'w dol' (zwieksz sort_prio)
-			$old_wsk_id = $wsk[ $id ];
-			if ($old_wsk_id + 1 == count($wsk)) return;
-			//echo'zamien "'.$id.'" na "'.$wsk_order[ $wsk[ $id ] + 1 ].'"';
-			$tmp = $wsk_order[ $wsk[ $id ] ];
-			$wsk_order[ $wsk[ $id ] ] = $wsk_order[ $wsk[ $id ] + 1 ];
-			$wsk_order[ $wsk[ $id ] + 1 ] = $tmp;
-		}
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">2 wsk ';print_r($wsk);echo'</pre>';
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">2 wsk_order ';print_r($wsk_order);echo'</pre>';
-		if (empty($wsk_order)) return;
-		foreach ($wsk_order as $k_osrt_prio => $v_wsk_id) {
-			$sql = "update `".$table."` set `SORT_PRIO`='".$k_osrt_prio."' where `ID`='".$v_wsk_id."'; ";
-			DB::query( $sql );
-		}
-	}
-}
-
-
 //   ==========  TASK - funkcje  ==============
 
 
@@ -652,145 +604,6 @@ function task_CRM_DEL_CRM_WSKAZNIK() {
 	echo'</p>';// .box
 }
 
-
-function &get_filter_for_table( $tbl ) {
-	Lib::loadClass('Filter');
-	$tree_filter = new Filter( $_GET, $tbl, 'session' );
-
-	// TODO: add trigger: on clear all filters - remove cookie, on tree key
-	//$tree_filter->
-
-	if ($tbl == 'CRM_PROCES') {
-		{// filtry
-			$filtr = array();
-			if (User_is_admin()) { // filtr_edit, only for admins
-				$filtr = array();
-				$filtr['TAK'] = '1';
-				$filtr['NIE'] = '0';
-				$tree_filter->add_filter( 'filtr_edit', $filtr, 'NIE', 'Edytuj' );
-			}
-			{ // filtr_drzewo - TODO: czy uzywane?
-				$filtr = array();
-				$filtr['ZWIN'] = '0';
-				$filtr['ROZWIN'] = '1';
-				//TODO: add js, onclick - remove cookie to hide tree
-				$tree_filter->add_filter( 'filtr_drzewo', $filtr, 'ROZWIN', 'Drzewo' );
-			}
-			{ // filtr_procesy
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_procesy', $filtr, '-', 'Procesy' );
-			}
-			{ // filtr_zasoby
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_zasoby', $filtr, '-', 'Zasoby' );
-			}
-			{ // filtr_opis
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_opis', $filtr, '-', 'Opisy' );
-			}
-			{ // filtr_img
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_img', $filtr, '-', 'IMG' );
-			}
-			{ // filtr_id
-				$filtr = array('search');
-				$tree_filter->add_filter( 'filtr_id', $filtr, '', 'Filtruj ID' );
-			}
-			{ // filtr_search_id
-				$filtr = array('search');
-				// TODO: add js search without page reload, add #TREE{ID}
-				$tree_filter->add_filter( 'filtr_search_id', $filtr, '', 'Wyszukaj ID' );
-			}
-			{ // filtr_view
-				$filtr = array();
-				$filtr['NOWY'] = '1';
-				$filtr['STARY'] = '0';
-				$tree_filter->add_filter( 'filtr_view', $filtr, 'NOWY', 'Widok' );
-			}
-			{ // filtr_ajax
-				$filtr = array();
-				$filtr['NIE'] = '0';
-				$filtr['TAK'] = '1';
-				$tree_filter->add_filter( 'filtr_ajax', $filtr, 'TAK', 'Ajax' );
-			}
-		}
-	}
-	else if ($tbl == 'CRM_LISTA_ZASOBOW') {
-		{// filtry
-			$filtr = array();
-			if (User_is_admin()) { // filtr_edit, only for admins
-				$filtr = array();
-				$filtr['TAK'] = '1';
-				$filtr['NIE'] = '0';
-				$tree_filter->add_filter( 'filtr_edit', $filtr, 'NIE', 'Edytuj' );
-			}
-			{ // filtr_drzewo
-				$filtr = array();
-				$filtr['ZWIN'] = '0';
-				$filtr['ROZWIN'] = '1';
-				$tree_filter->add_filter( 'filtr_drzewo', $filtr, 'ZWIN', 'Drzewo' );
-			}
-			{ // filtr_ob
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_ob', $filtr, '-', 'OB' );
-			}
-			{ // filtr_img
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_img', $filtr, '-', 'IMG' );
-			}
-			{ // filtr_opis
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_opis', $filtr, '-', 'Opisy' );
-			}
-			{ // filtr_ids
-				$filtr = array();
-				$filtr['-'] = '0';
-				$filtr['+'] = '1';
-				$tree_filter->add_filter( 'filtr_ids', $filtr, '-', 'IDS' );
-			}
-			{ // filtr_id
-				$filtr = array('search');
-				$tree_filter->add_filter( 'filtr_id', $filtr, '', 'Filtruj ID' );
-			}
-			{ // filtr_search_id
-				$filtr = array('search');
-				$tree_filter->add_filter( 'filtr_search_id', $filtr, '', 'Wyszukaj ID' );
-			}
-			{ // filtr_view
-				$filtr = array();
-				$filtr['NOWY'] = '1';
-				$filtr['STARY'] = '0';
-				$tree_filter->add_filter( 'filtr_view', $filtr, 'NOWY', 'Widok' );
-			}
-			{ // filtr_ajax
-				$filtr = array();
-				$filtr['TAK'] = '1';
-				$filtr['NIE'] = '0';
-				$tree_filter->add_filter( 'filtr_ajax', $filtr, 'TAK', 'Ajax' );
-			}
-		}
-	}
-	else {
-		// unknown table
-	}
-	return $tree_filter;
-}
-
-
 function fun_USERS_COLUMN() {
 	$arg = V::get('arg', '', $_GET);
 	$col_id = V::get('col_id', '', $_GET);
@@ -1373,6 +1186,7 @@ function task_CRM_WYSWIETL_OBOWIAZKI() {
 			w.`ID_ZASOB`=".$_GET['CLZ_ID']."
 			and w.`A_STATUS` in('WAITING','NORMAL')
 			and p.`A_STATUS` in('WAITING','NORMAL')
+			order by p.SORT_PRIO
 	";
 	$res = $db->query($sql);
 	while ($r = $db->fetch($res)) {
@@ -1524,101 +1338,71 @@ function fun_SHOW_EXTERNAL_IMAGE() {
 	$remote_table = V::get('tbl', '', $_REQUEST);
 	$remote_id = V::get('id', '', $_REQUEST, 'int');
 	$number = V::get('number', '', $_REQUEST, 'int');
-	$image_resize = V::get('resize', '', $_REQUEST);
-
-	Lib::loadClass('DB_Image');
+	$imageResize = V::get('resize', '', $_REQUEST);
+	$DBG = (V::get('DBG', 0, $_REQUEST, 'int') > 0);
 
-	// check remote id
 	if ($remote_id <= 0) {
 		header('HTTP/1.1 400: Bad Request');
 		header('Warning: wrong ID L.' . __LINE__);
 		exit;
 	}
 
-	// check remote table
-	$remote_tables = DB_Image::conf_get('remote_tables');
-	if (!in_array($remote_table, $remote_tables)) {
+	if (!DB_Image::tableIsAllowed($remote_table)) {
 		header('HTTP/1.1 400: Bad Request');
 		header('Warning: table not allowed L.' . __LINE__);
 		exit;
 	}
 
-	$db = DB::getDB();
-	$sql = "select `ID`, `TYPE`, `SIZE`, `IMAGE`, `WIDTH`, `HEIGHT`
-			, UNIX_TIMESTAMP(`A_CREATE_DATE`) as A_CREATE_DATE_TS
-		from `".DB_Image::conf_get_table_name()."`
-		where
-			`REMOTE_ID`='".$remote_id."'
-			and `REMOTE_TABLE`='".$remote_table."'
-		order by `ID` asc
-		limit 1 offset ".$number."
-	";
-
-	$res = $db->query($sql);
-	if (!$db->num_rows($res)) {
+	$image_row = DB_Image::getImage($remote_table, $remote_id, $number);
+	if (!$image_row) {
 		header('HTTP/1.1 400: Bad Request');
-		header('Warning: images not found in db L.' . __LINE__);
+		header('Warning: image not found in db L.' . __LINE__);
 		exit;
 	}
 
-	if ($image_row = $db->fetch( $res )) {
-		$etag = md5($image_row->ID . $image_row->A_CREATE_DATE_TS);
-		if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $image_row->A_CREATE_DATE_TS
-			|| trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
-			//header("HTTP/1.1 304 Not Modified");
-			//exit;
-		}
-		$expire_date = mktime(0, 0, 0, date('m') + 3, date('d'), date('Y'));
-
-		if ($image_resize) {
-			list($resize_w, $resize_h) = explode('x', $image_resize, 2);
-			$resize_w = intval($resize_w); $resize_h = intval($resize_h);
-			if ($resize_w > 0 && $resize_h > 0) {
-				$im = imagecreatefromstring( $image_row->IMAGE );
-				$image_resized = DB_Image::resize_image_from_data($im, $resize_w, $resize_h);
-
-				header("Content-type: ".$image_row->TYPE);
-				//header("Cache-control: public");
-				header("Cache-control: public");
-				header("Pragma: public");// default 'no-cache'
-				header("Etag: ".$etag);
-				header("Expires: " . gmdate("D, d M Y H:i:s", $expire_date) . " GMT");
-				header("Last-Modified: " . gmdate("D, d M Y H:i:s", $image_row->A_CREATE_DATE_TS) . " GMT");
-				if ($image_row->TYPE == 'image/png') {
-					imagepng($image_resized);
-				} else if ($image_row->TYPE == 'image/jpeg' || $image_row->TYPE == 'image/jpg') {
-					imagejpeg($image_resized);
-				} else if ($image_row->TYPE == 'image/gif') {
-					imagegif($image_resized);
-				}
-			} else {
-				echo'ERROR wrong param resize (WxH)';
-			}
+	$etag = md5($image_row->ID . $image_row->A_CREATE_DATE_TS);
+	if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $image_row->A_CREATE_DATE_TS
+		|| trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
+		//header("HTTP/1.1 304 Not Modified");
+		//exit;
+	}
+	$expire_date = mktime(0, 0, 0, date('m') + 3, date('d'), date('Y'));
+
+	$maxWidth = 0;
+	$maxHeight = 0;
+	if ($imageResize) {
+		list($maxWidth, $maxHeight) = explode('x', $imageResize, 2);
+		$maxWidth = intval($maxWidth);
+		$maxHeight = intval($maxHeight);
+		if ($maxWidth <= 0 || $maxHeight <= 0) {
+			header('HTTP/1.1 400: Bad Request');
+			echo'ERROR wrong param resize (WxH)';
 			exit;
 		}
+	}
 
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">';print_r($image_row);echo'</pre>';
-		//header("Content-type: ".$image_row->TYPE);
-		header("Content-type: ".$image_row->TYPE);
+	if (!$DBG) {
+		header("Content-type: {$image_row->TYPE}");
 		header("Cache-control: public");
 		header("Pragma: public");// default 'no-cache'
-		header("Etag: ".$etag);
-		header("Content-length: ".$image_row->SIZE);
+		header("Etag: {$etag}");
+		if (!$imageResize) {
+			header("Content-length: {$image_row->SIZE}");
+		}
 		header("Expires: " . gmdate("D, d M Y H:i:s", $expire_date) . " GMT");
 		header("Last-Modified: " . gmdate("D, d M Y H:i:s", $image_row->A_CREATE_DATE_TS) . " GMT");
-		//echo stripslashes($image_row->IMAGE);
-		print $image_row->IMAGE;
-		//file_put_contents('/home/pl/projekty/kyoritsu.pl/src/1.jpg', $image_row->IMAGE);
+	}
+	if ($imageResize) {
+		print DB_Image::resizeImageFromBlob($image_row->IMAGE, $image_row->TYPE, $maxWidth, $maxHeight);
 	} else {
-		header('HTTP/1.1 400: Bad Request');
-		header('Warning: image not found in db L.' . __LINE__);
+		print $image_row->IMAGE;
 	}
 	exit;
 }
 
 
 function fun_SHOW_IMAGE() {
-	$image_id = V::get('image_id', '', $_REQUEST, 'int');
+	$image_id = V::get('image_id', 0, $_REQUEST, 'int');
 
 	if ($image_id <= 0) {
 		header('HTTP/1.1 400: Bad Request');
@@ -1626,31 +1410,23 @@ function fun_SHOW_IMAGE() {
 		exit;
 	}
 
-	Lib::loadClass('DB_Image');
-
-	$db = DB::getDB();
-	$image_row = DB::get_by_id( DB_Image::conf_get_table_name(), $image_id);
+	$image_row = DB_Image::getImageById($image_id);
 	if (!$image_row) {
 		header('HTTP/1.1 400: Bad Request');
 		header('Warning: image not found in db L.' . __LINE__);
 		exit;
 	}
 
-	//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">';print_r($image_row);echo'</pre>';
-	//header("Content-type: ".$image_row->TYPE);
-	// TODO: header cache
 	header("Content-type: ".$image_row->TYPE);
 	header("Content-length: ".$image_row->SIZE);
-	//echo stripslashes($image_row->IMAGE);
 	print $image_row->IMAGE;
 	exit;
-	//file_put_contents('/home/pl/projekty/kyoritsu.pl/src/1.jpg', $image_row->IMAGE);
 }
 
 
 function fun_IMAGE_ADD() {
 	$remote_table = V::get('tbl', '', $_REQUEST);
-	$remote_id = V::get('id', '', $_REQUEST, 'int');
+	$remote_id = V::get('id', 0, $_REQUEST, 'int');
 	$task = V::get('task', '', $_REQUEST);
 
 	$thiss = new stdClass();
@@ -1658,8 +1434,6 @@ function fun_IMAGE_ADD() {
 	$errors = array();
 	$msgs = array();
 
-	Lib::loadClass('DB_Image');
-
 	// check remote id
 	if ($remote_id <= 0) {
 		echo'<p>';
@@ -1671,22 +1445,10 @@ function fun_IMAGE_ADD() {
 	}
 
 	// check remote table
-	$remote_tables = DB_Image::conf_get('remote_tables');
-	if (!in_array($remote_table, $remote_tables)) {
+	if (!DB_Image::tableIsAllowed($remote_table)) {
 		$errors[] = "Error table not allowed to add image";
 	}
 
-	if (0) {
-		if ($ARG1_VAL != 'DODAJ_PLIK') {
-			if ($_SESSION['CURRENT_MENU'] == $thiss->DETECT_EDIT_FUNCTION) {
-				if (strstr($_SESSION[$thiss->DETECT_TABLE_COLUMN]['PERMEDIT']['ITEM_IMAGE_REMOTE'],"W")) {
-					echo '<a target="_blank" href="'.$_SERVER['PHP_SELF']."?function_init=typespecial_ITEM_IMAGE_REMOTE&ARG1_VAL=DODAJ_PLIK&HEADER_NOT_INIT=YES".'">'."DODAJ_PLIK".'</a>';
-				}
-			}
-			return;
-		}
-	}
-
 	// task
 	$task = V::get('task', '', $_REQUEST);
 	if ($task == 'REMOVE') {// TODO: przerobic na funkcje, zwrocic msg, pokazac w body
@@ -1708,7 +1470,7 @@ function fun_IMAGE_ADD() {
 		}
 
 		if (empty($errors)) {
-			$affected = DB_Image::delete_image($req['ID'], $req['REMOTE_TABLE'], $req['REMOTE_ID']);
+			$affected = DB_Image::deleteImage($req['ID'], $req['REMOTE_TABLE'], $req['REMOTE_ID']);
 			if ($affected == 1) {
 				$msgs[] = '<p>'."Usunieto zdjecie ID=".$req['ID'].'</p>';
 			} else {
@@ -1722,7 +1484,7 @@ function fun_IMAGE_ADD() {
 		//echo '<p>Please select a file</p>';
 	}
 	else {
-		$errors = DB_Image::upload_image($remote_table, $remote_id, $_FILES['userfile']);
+		$errors = DB_Image::uploadImage($remote_table, $remote_id, $_FILES['userfile']);
 		// give praise and thanks to the php gods
 		if (empty($errors)) {
 			$msgs[] = '<p>Thank you for submitting</p>';
@@ -1763,7 +1525,7 @@ function fun_IMAGE_ADD() {
 		echo"Rodzaj obrazka: ";
 		echo'<input type="text" name="'."DEST".'" value="'."".'" />';
 		$select_arr = array();
-		$select_arr = DB_Image::conf_get_options( $thiss->DETECT_TABLE_NAME );
+		$select_arr = DB_Image::conf_get_options($thiss->DETECT_TABLE_NAME);
 
 		if (!empty($select_arr)) {
 			echo' ';
@@ -1784,7 +1546,7 @@ function fun_IMAGE_ADD() {
 
 
 // TODO: show images, mv to function {
-	$images = DB_Image::get_images($thiss->DETECT_TABLE_NAME, $remote_id);
+	$images = DB_Image::getImages($thiss->DETECT_TABLE_NAME, $remote_id);
 
 	echo'<div class="box box-blue" style="overflow:hidden">';
 	if (empty($images)) {
@@ -1808,7 +1570,7 @@ function fun_IMAGE_ADD() {
 					echo''.$r->NAME.'<br />';
 					echo''.$r->DEST.'<br />';
 					echo''.$r->A_CREATE_DATE.'<br />';
-					echo''.DB_Image::show_size($r->SIZE).' '.$r->WIDTH.'x'.$r->HEIGHT.'<br />';
+					echo''.DB_Image::showSize($r->SIZE).' '.$r->WIDTH.'x'.$r->HEIGHT.'<br />';
 					echo'<img src="'.$link_src.'" '.$st.'/>';
 				echo'</td>';
 			echo'</tr>';
@@ -2421,7 +2183,12 @@ function tree_callback__show_item_from_CRM_PROCES( &$r, &$tree ) {
 				echo App::link("v", array('function_init'=>'SORT_PRIO_WSKAZNIK', 'arg1'=> $w->CW_ID, 'arg1_val'=>'dw','_hash'=>rand(0,9999),'#'=>'TREE'.$r->ID), array('class'=>"btn-clean", 'title'=>"w dol"));
 				echo App::link("V", array('function_init'=>'SORT_PRIO_WSKAZNIK', 'arg1'=> $w->CW_ID, 'arg1_val'=>'downdown','_hash'=>rand(0,9999),'#'=>'TREE'.$r->ID), array('class'=>"btn-clean", 'title'=>"w dol o 5 pol"));
 				echo' ';
-				echo App::link("E", "?task=CRM_EDIT_CRM_WSKAZNIK&EDIT=".$w->CW_ID."&ID=".$w->CW_ID, array('title'=>'Edytuj', 'class'=>'btn-p5'));
+				
+				if ($tree->get_param('WskaznikTblId')) {
+					echo App::link("E", "index.php?MENU_INIT=VIEWTABLE_AJAX&ZASOB_ID=".$tree->get_param('WskaznikTblId')."#EDIT/".$w->CW_ID, array('title'=>'Edytuj', 'class'=>'btn-p5'));
+				} else {
+					echo App::link("E", "?task=CRM_EDIT_CRM_WSKAZNIK&EDIT=".$w->CW_ID."&ID=".$w->CW_ID, array('title'=>'Edytuj', 'class'=>'btn-p5'));
+				}
 
 				if ($tree->get_param('ZasobTblId') > 0) {
 					echo App::link("F", "index.php?MENU_INIT=VIEWTABLE_AJAX&ZASOB_ID=".$tree->get_param('ZasobTblId')."#FILES/".$w->ID, array('title'=>'Pliki', 'class'=>'btn-p5'));
@@ -2950,6 +2717,18 @@ function tree_callback__show_item_from_CRM_LISTA_ZASOBOW( &$r, &$tree ) {
 			$external_ids_allowed_type[] = 'DANE';
 			$external_ids_allowed_type[] = 'SIP_ACCOUNT';
 			$external_ids_allowed_type[] = 'PODMIOT';
+			$external_ids_allowed_type[] = 'URZADZENIA_I_OZNACZENIA_BHP';
+			$external_ids_allowed_type[] = 'SOFTWARE';
+			$external_ids_allowed_type[] = 'WYPOSAZENIE_LOKALU';
+			$external_ids_allowed_type[] = 'KUWETA';
+			$external_ids_allowed_type[] = 'DOSTEP-UPRAWNIENIA';  
+			$external_ids_allowed_type[] = 'APLIKACJA'; 
+			$external_ids_allowed_type[] = 'LOKALIZACJA';  
+			$external_ids_allowed_type[] = 'KOMPUTER';  
+			$external_ids_allowed_type[] = 'MATERIAL_EKSPLOATACYJNY';
+			$external_ids_allowed_type[] = 'SOFTWARE';
+			$external_ids_allowed_type[] = 'OBSZAR';			
+			
 			if (in_array($r->TYPE, $external_ids_allowed_type)) {
 				echo '<span class="external-ids">' . "{";
 				echo App::link_ajax("get IDS", "ajax_zasob_search_external_ids", array('zasob_id'=>$r->ID), array('js_result_type'=>'override', 'js_result'=>''));

+ 400 - 279
SE/se-lib/DB_Image.php

@@ -3,327 +3,448 @@
 
 class DB_Image {
 
-public static function conf_get( $key ) {
-	static $conf;
-	if (empty($conf)) {
-		$conf['table_name'] = 'CRM_IMAGE';
-		$conf['max_size'] = 1024 * 1024 * 16;// MAX for MEDIUMBLOB field
-		$conf['allowed_types'] = array();
-		$conf['allowed_types'][] = 'image/png';
-		$conf['allowed_types'][] = 'image/jpeg';
-		$conf['allowed_types'][] = 'image/gif';
-
-		$conf['remote_tables'] = array();
-		$conf['remote_tables'][] = 'CRM_LISTA_ZASOBOW';
-		$conf['remote_tables'][] = 'CRM_PROCES';
-		$conf['remote_tables'][] = 'CRM_WSKAZNIK';
-
-		$conf['desc_options'] = array();
-		$conf['desc_options']['CRM_LISTA_ZASOBOW'] = array();
-		$conf['desc_options']['CRM_PROCES'] = array();
-		$conf['desc_options']['CRM_WSKAZNIK'] = array();
-
-		$conf['desc_options_conf'] = array();
-		$conf['desc_options_conf']['CRM_LISTA_ZASOBOW'] = array();
-		$conf['desc_options_conf']['CRM_PROCES'] = array();
-		$conf['desc_options_conf']['CRM_WSKAZNIK'] = array();
-
-		$options = array();
-		$options['screenshot'] = "screenshot (800x600)";
-		$options['icon'] = "icon (16x16)";
-
-		$conf['desc_options']['CRM_LISTA_ZASOBOW'] = $options;
-		$conf['desc_options']['CRM_PROCES'] = $options;
-		$conf['desc_options']['CRM_WSKAZNIK'] = $options;
-
-		$desc_options_conf = array();
-		$desc_options_conf['screenshot']['max_width'] = 800;
-		$desc_options_conf['screenshot']['max_height'] = 600;
-		$desc_options_conf['icon']['max_width'] = 16;
-		$desc_options_conf['icon']['max_height'] = 16;
-
-		$conf['desc_options_conf']['CRM_LISTA_ZASOBOW'] = $desc_options_conf;
-		$conf['desc_options_conf']['CRM_PROCES'] = $desc_options_conf;
-		$conf['desc_options_conf']['CRM_WSKAZNIK'] = $desc_options_conf;
+	public static function calculateThumbImageSize($width, $height, $maxWidth, $maxHeight) {
+		$width     = intval($width);
+		$height    = intval($height);
+		$maxWidth  = intval($maxWidth);
+		$maxHeight = intval($maxHeight);
+		if ($width <= 0 || $height <= 0 || $maxWidth <= 0 || $maxHeight <= 0) {
+			throw new Exception("Wrong params");
+		}
+		list($newWidth, $newHeight) = array($width, $height);
+
+		if ($width >= $maxWidth || $height >= $maxWidth) {
+			$ratioWidth  = $maxWidth  / $width;
+			$ratioHeight = $maxHeight / $height;
+
+			if ($ratioWidth > $ratioHeight) {
+				$ratio = $ratioHeight;
+			} else {
+				$ratio = $ratioWidth;
+			}
+
+			$newWidth  = intval($width  * $ratio);
+			$newHeight = intval($height * $ratio);
+		}
+		return array($newWidth, $newHeight);
 	}
-	if (array_key_exists($key, $conf)) {
-		return $conf[ $key ];
+
+	public static function resizeImageFromBlob($imageBlob, $type, $maxWidth, $maxHeight) {
+		$resizedImageBlob = null;
+		list($w, $h) = self::getImageGeometryFromBlob($imageBlob);
+		list($newWidth, $newHeight) = self::calculateThumbImageSize($w, $h, $maxWidth, $maxHeight);
+		if ($newW == $w && $newH == $h) {
+			return $imageBlob;
+		}
+
+		if (class_exists('Imagick')) {
+			$im = new Imagick();
+			$im->readImageBlob($imageBlob);
+			$im->thumbnailImage($newWidth, $newHeight, true);
+			$resizedImageBlob = $im->getImageBlob();
+		} else {
+			$im = imagecreatefromstring($imageBlob);
+			$image_resized = self::resize_image_from_data($im, $newWidth, $newHeight);
+			ob_start();
+			if ($type == 'image/png') {
+				imagepng($image_resized);
+			} else if ($type == 'image/jpeg' || $type == 'image/jpg') {
+				imagejpeg($image_resized);
+			} else if ($type == 'image/gif') {
+				imagegif($image_resized);
+			}
+			$resizedImageBlob = ob_get_contents();
+			ob_clean();
+		}
+		return $resizedImageBlob;
 	}
-	return null;
-}
 
-public static function conf_get_table_name() {
-	return self::conf_get('table_name');
-}
+	public static function getImageGeometryFromBlob($imageBlob) {
+		if (class_exists('Imagick')) {
+			$im = new Imagick();
+			$im->readImageBlob($imageBlob);
+			$geometry = $im->getImageGeometry();
+			$w = $geometry['width'];
+			$h = $geometry['height'];
+		} else {
+			$im = imagecreatefromstring($imageBlob);
+			$w = imagesx($im);
+			$h = imagesy($im);
+		}
+		return array($w, $h);
+	}
 
-/*
- * Get options for table.
- */
-public static function conf_get_options( $table ) {
-	$ret = array();
-	$arr = self::conf_get('desc_options');
-	if (array_key_exists($table, $arr)) {
-		return $arr[$table];
+	public static function getImage($remote_table, $remote_id, $number = 0) {
+		$db = DB::getDB();
+		$sql = "select `ID`, `TYPE`, `SIZE`, `IMAGE`, `WIDTH`, `HEIGHT`
+				, UNIX_TIMESTAMP(`A_CREATE_DATE`) as A_CREATE_DATE_TS
+			from `".self::conf_get_table_name()."`
+			where
+				`REMOTE_ID`='{$remote_id}'
+				and `REMOTE_TABLE`='{$remote_table}'
+			order by `ID` asc
+			limit 1 offset {$number}
+		";
+
+		$res = $db->query($sql);
+		if (!$db->num_rows($res)) {
+			return null;
+		}
+		return $db->fetch($res);
 	}
-	return $ret;
-}
 
-/*
- * Get config for all options.
- */
-public static function conf_get_options_conf( $table ) {
-	$ret = array();
-	$arr = self::conf_get('desc_options_conf');
-	if (array_key_exists($table, $arr)) {
-		return $arr[$table];
+	public static function getImageById($imageId) {
+		$db = DB::getDB();
+		$sql = "select `ID`, `TYPE`, `SIZE`, `IMAGE`, `WIDTH`, `HEIGHT`
+				, UNIX_TIMESTAMP(`A_CREATE_DATE`) as A_CREATE_DATE_TS
+			from `".self::conf_get_table_name()."`
+			where
+				`ID`='{$imageId}'
+		";
+
+		$res = $db->query($sql);
+		return $db->fetch($res);
+	}
+
+	public static function tableIsAllowed($remote_table) {
+		$remote_tables = self::conf_get('remote_tables');
+		return in_array($remote_table, $remote_tables);
 	}
-	return $ret;
-}
 
-/*
- * Get config for selected option.
- */
-public static function conf_get_option_conf( $table, $key ) {
-	$ret = array();
-	$arr = self::conf_get('desc_options_conf');
-	if (array_key_exists($table, $arr)) {
-		if (array_key_exists($key, $arr[$table])) {
-			return $arr[$table][$key];
+	public static function conf_get($key) {
+		static $conf;
+		if (empty($conf)) {
+			$conf['table_name'] = 'CRM_IMAGE';
+			$conf['max_size'] = 1024 * 1024 * 16;// MAX for MEDIUMBLOB field
+			$conf['allowed_types'] = array();
+			$conf['allowed_types'][] = 'image/png';
+			$conf['allowed_types'][] = 'image/jpeg';
+			$conf['allowed_types'][] = 'image/gif';
+
+			$conf['remote_tables'] = array();
+			$conf['remote_tables'][] = 'CRM_LISTA_ZASOBOW';
+			$conf['remote_tables'][] = 'CRM_PROCES';
+			$conf['remote_tables'][] = 'CRM_WSKAZNIK';
+
+			$conf['desc_options'] = array();
+			$conf['desc_options']['CRM_LISTA_ZASOBOW'] = array();
+			$conf['desc_options']['CRM_PROCES'] = array();
+			$conf['desc_options']['CRM_WSKAZNIK'] = array();
+
+			$conf['desc_options_conf'] = array();
+			$conf['desc_options_conf']['CRM_LISTA_ZASOBOW'] = array();
+			$conf['desc_options_conf']['CRM_PROCES'] = array();
+			$conf['desc_options_conf']['CRM_WSKAZNIK'] = array();
+
+			$options = array();
+			$options['screenshot'] = "screenshot (800x600)";
+			$options['icon'] = "icon (16x16)";
+
+			$conf['desc_options']['CRM_LISTA_ZASOBOW'] = $options;
+			$conf['desc_options']['CRM_PROCES'] = $options;
+			$conf['desc_options']['CRM_WSKAZNIK'] = $options;
+
+			$desc_options_conf = array();
+			$desc_options_conf['screenshot']['max_width'] = 800;
+			$desc_options_conf['screenshot']['max_height'] = 600;
+			$desc_options_conf['icon']['max_width'] = 16;
+			$desc_options_conf['icon']['max_height'] = 16;
+
+			$conf['desc_options_conf']['CRM_LISTA_ZASOBOW'] = $desc_options_conf;
+			$conf['desc_options_conf']['CRM_PROCES'] = $desc_options_conf;
+			$conf['desc_options_conf']['CRM_WSKAZNIK'] = $desc_options_conf;
+		}
+		if (array_key_exists($key, $conf)) {
+			return $conf[$key];
 		}
+		return null;
 	}
-	return $ret;
-}
 
-public static function is_allowed_type( $type ) {
-	$allowed_types = self::conf_get('allowed_types');
-	if (in_array($type, $allowed_types)) {
-		return true;
+	public static function conf_get_table_name() {// TODO: RM Legacy
+		return self::getStorageTableName();
 	}
-	return false;
-}
 
-public static function read_image_data( $file, $mime_type ){
-	$im = null;
-	if ($mime_type == 'image/jpeg') {
-		$im = imagecreatefromjpeg( $file );
-	} else if ($mime_type == 'image/png') {
-		$im = imagecreatefrompng( $file );
-	} else if ($mime_type == 'image/gif') {
-		$im = imagecreatefromgif( $file );
+	public static function getStorageTableName() {
+		return self::conf_get('table_name');
 	}
-	return $im;
-}
 
-public static function get_images($remote_table, $remote_id) {
-	$db = DB::getDB();
-	$images = array();
-	$sql = "select
-			t.`ID`, t.`NAME`, t.`SIZE`, t.`TYPE`, t.`WIDTH`, t.`HEIGHT`
-			, t.`DEST`, t.`A_CREATE_DATE`
-			, t.`REMOTE_TABLE`, t.`REMOTE_ID`
-			, UNIX_TIMESTAMP(`A_CREATE_DATE`) as A_CREATE_DATE_TS
-		from `".self::conf_get_table_name()."` as t
-		where
-			t.`REMOTE_TABLE`='".$remote_table."'
-			and t.`REMOTE_ID`='".$remote_id."'
-	";
-	$res = $db->query($sql);
-	while ($r = $db->fetch( $res )) {
-		$images[] = $r;
+	public static function conf_get_options($table) {// TODO: RM Legacy
+		return self::getTableConfig($table);
 	}
-	return $images;
-}
 
-/**
- * Try to upload image to DB.
- * @returns Array of errors
- */
-public static function upload_image($remote_table, $remote_id, $req_file_data) {
-	$errors = array();
-	$maxsize = self::conf_get('max_size');
-
-	//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$_FILES = ';print_r($_FILES);echo'</pre>';
-
-	if (is_uploaded_file($req_file_data['tmp_name'])) {
-		// check the file is less than the maximum file size
-		if ($req_file_data['size'] < $maxsize) {
-			// prepare the image for insertion
-			//$imgData = mysql_real_escape_string(file_get_contents($req_file_data['tmp_name']), $conn);// nie dziala mysql_real_escape_string
-			$fp = fopen($req_file_data['tmp_name'], 'r');
-			$imgData = fread($fp, filesize($req_file_data['tmp_name']));
-			$imgData = addslashes($imgData);
-			fclose($fp);
-
-			// get the image info..
-			$size = getimagesize($req_file_data['tmp_name']);
-
-			$obj = array();
-			$obj['DEST'] = (isset($_REQUEST['DEST']))? $_REQUEST['DEST'] : '';
-			$obj['TYPE'] = $size['mime'];
-			$obj['IMAGE'] = $imgData;
-			$obj['WIDTH'] = $size[0];
-			$obj['HEIGHT'] = $size[1];
-			$obj['NAME'] = $req_file_data['name'];
-			$obj['SIZE'] = $req_file_data['size'];
-			$obj['REMOTE_TABLE'] = $remote_table;
-			$obj['REMOTE_ID'] = $remote_id;
-
-			// check if type is allowed to upload
-			if (!DB_Image::is_allowed_type($obj['TYPE'])) {
-				$errors[] = 'File type "'.$obj['TYPE'].'" is not allowed.';
-				return $errors;
-			}
+	public static function getTableConfig($table) {
+		$ret = array();
+		$arr = self::conf_get('desc_options');
+		if (array_key_exists($table, $arr)) {
+			return $arr[$table];
+		}
+		return $ret;
+	}
 
-			// convert image if selected option
-			if ($obj['DEST']) {
-				$options_conf = DB_Image::conf_get_option_conf( $remote_table, $obj['DEST'] );
-				if (!empty($options_conf)) {
-					$max_width = 0;
-					$max_height = 0;
-					if (isset($options_conf['max_height']) && $obj['HEIGHT'] > $options_conf['max_height']) {
-						$max_height = $options_conf['max_height'];
-					}
-					if (isset($options_conf['max_width']) && $obj['WIDTH'] > $options_conf['max_width']) {
-						$max_width = $options_conf['max_width'];
-					}
-					if ($max_height || $max_width) {
-						//$img = DB_Image::resize_image($req_file_data['tmp_name'], $max_width, $max_height);
-						//open image, from file to data
-
-						// read data
-						$im = DB_Image::read_image_data($req_file_data['tmp_name'], $obj['TYPE']);
-						// resize image
-						$im = DB_Image::resize_image_from_data($im, $max_width, $max_height);
-						ob_start();
-							imagejpeg($im);
-						$obj['IMAGE'] = ob_get_clean();
-
-						$obj['SIZE'] = strlen($obj['IMAGE']);
-						$obj['IMAGE'] = addslashes($obj['IMAGE']);
-						$obj['WIDTH'] = imagesx($im);
-						$obj['HEIGHT'] = imagesy($im);
-					}
-				}
+	public static function conf_get_options_conf($table) {// TODO: RM Not used ?
+		$ret = array();
+		$arr = self::conf_get('desc_options_conf');
+		if (array_key_exists($table, $arr)) {
+			return $arr[$table];
+		}
+		return $ret;
+	}
+
+	public static function conf_get_option_conf($table, $key) {// TODO: used only in upload_image
+		$ret = array();
+		$arr = self::conf_get('desc_options_conf');
+		if (array_key_exists($table, $arr)) {
+			if (array_key_exists($key, $arr[$table])) {
+				return $arr[$table][$key];
 			}
+		}
+		return $ret;
+	}
 
-			//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">size = ';print_r($size);echo'</pre>';
+	public static function is_allowed_type($type) {// TODO: used only in upload_image
+		$allowed_types = self::conf_get('allowed_types');
+		if (in_array($type, $allowed_types)) {
+			return true;
+		}
+		return false;
+	}
 
-			$sql_arr = array();
-			foreach ($obj as $key => $val) {
-				$sql_arr["`".$key."`"] = "'".$val."'";
+	public static function readImageBlobFromFile($file, $mimeType) {
+		$imBlob = null;
+		if (class_exists('Imagick')) {
+			$im = new Imagick($file);
+			$imBlob = $im->getImageBlob();
+		} else {
+			if ($mimeType == 'image/jpeg') {
+				$im = imagecreatefromjpeg($file);
+			} else if ($mimeType == 'image/png') {
+				$im = imagecreatefrompng($file);
+			} else if ($mimeType == 'image/gif') {
+				$im = imagecreatefromgif($file);
 			}
-			$sql = "insert into `".self::conf_get_table_name()."` (".implode(",", array_keys($sql_arr)).") values (".implode(",", array_values($sql_arr)).") ; ";
+			ob_start();
+			if ($mimeType == 'image/png') {
+				imagepng($im);
+			} else if ($mimeType == 'image/jpeg' || $mimeType == 'image/jpg') {
+				imagejpeg($im);
+			} else if ($mimeType == 'image/gif') {
+				imagegif($im);
+			}
+			$imBlob = ob_get_contents();
+			ob_clean();
+		}
+		return $imBlob;
+	}
 
-			// insert the image
-			//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">sql = ';print_r($sql);echo'</pre>';
-			$db = DB::getDB();
+	public static function read_image_data($file, $mime_type) {// TODO: used only in upload_image
+		$im = null;
+		if ($mime_type == 'image/jpeg') {
+			$im = imagecreatefromjpeg($file);
+		} else if ($mime_type == 'image/png') {
+			$im = imagecreatefrompng($file);
+		} else if ($mime_type == 'image/gif') {
+			$im = imagecreatefromgif($file);
+		}
+		return $im;
+	}
 
-			if (!$db->query($sql)) {
-				$errors[] = 'Unable to upload file - sql error';
-				//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">mysql err: '.mysql_errno($conn);var_dump(mysql_error($conn));echo'</pre>';
-				//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">sql: ';print_r($sql);echo'</pre>';
-			}
+	public static function get_images($remote_table, $remote_id) {// TODO: RM Legacy
+		return self::getImages($remote_table, $remote_id);
+	}
 
-			self::update_remote_table_stat( $remote_table, $remote_id );
+	public static function getImages($remote_table, $remote_id) {
+		$db = DB::getDB();
+		$images = array();
+		$sql = "select
+				t.`ID`, t.`NAME`, t.`SIZE`, t.`TYPE`, t.`WIDTH`, t.`HEIGHT`
+				, t.`DEST`, t.`A_CREATE_DATE`
+				, t.`REMOTE_TABLE`, t.`REMOTE_ID`
+				, UNIX_TIMESTAMP(`A_CREATE_DATE`) as A_CREATE_DATE_TS
+			from `".self::conf_get_table_name()."` as t
+			where
+				t.`REMOTE_TABLE`='{$remote_table}'
+				and t.`REMOTE_ID`='{$remote_id}'
+		";
+		$res = $db->query($sql);
+		while ($r = $db->fetch($res)) {
+			$images[] = $r;
 		}
+		return $images;
 	}
-	else {
-		// if the file is not less than the maximum allowed, print an error
-		$errors[] = 'File exceeds the Maximum File limit';
+
+	/**
+	 * Try to upload image to DB.
+	 * @returns Array of errors
+	 */
+	public static function upload_image($remote_table, $remote_id, $req_file_data) {// TODO: RM -> moved to uploadImage
+		return self::uploadImage($remote_table, $remote_id, $req_file_data);
 	}
-	return $errors;
-}
 
-public static function delete_image($id, $remote_table, $remote_id) {
-	$db = DB::getDB();
-	$sql = "delete from `".self::conf_get_table_name()."`
-		where
-			`ID`='".$id."'
-			and `REMOTE_ID`='".$remote_id."'
-			and `REMOTE_TABLE`='".$remote_table."'
-		limit 1
-	";
-	//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">sql delete = ';print_r($sql);echo'</pre>';
-	$db->query( $sql );
-	$affected = $db->affected_rows();
-
-	self::update_remote_table_stat( $remote_table, $remote_id );
-
-	return $affected;
-}
+	public static function uploadImage($remote_table, $remote_id, $req_file_data) {
+		$errors = array();
+		$maxsize = self::conf_get('max_size');
+
+		if (is_uploaded_file($req_file_data['tmp_name'])) {
+			if ($req_file_data['size'] < $maxsize) {
+				$fp = fopen($req_file_data['tmp_name'], 'r');
+				$imgData = fread($fp, filesize($req_file_data['tmp_name']));
+				$imgData = addslashes($imgData);
+				fclose($fp);
+
+				$size = getimagesize($req_file_data['tmp_name']);
+
+				$sqlObj = array();
+				$sqlObj['DEST'] = (isset($_REQUEST['DEST']))? $_REQUEST['DEST'] : '';
+				$sqlObj['TYPE'] = $size['mime'];
+				$sqlObj['IMAGE'] = $imgData;
+				$sqlObj['WIDTH'] = $size[0];
+				$sqlObj['HEIGHT'] = $size[1];
+				$sqlObj['NAME'] = $req_file_data['name'];
+				$sqlObj['SIZE'] = $req_file_data['size'];
+				$sqlObj['REMOTE_TABLE'] = $remote_table;
+				$sqlObj['REMOTE_ID'] = $remote_id;
+
+				// check if type is allowed to upload
+				if (!self::is_allowed_type($sqlObj['TYPE'])) {
+					$errors[] = 'File type "'.$sqlObj['TYPE'].'" is not allowed.';
+					return $errors;
+				}
 
-/**
- * Updates field ITEM_IMAGE_REMOTE in remote table.
- * TODO: check if field exists!
- */
-public static function update_remote_table_stat($remote_table, $remote_id) {
-	// update stat `ITEM_IMAGE_REMOTE`
-	$sql = "update `".$remote_table."`
-			set `A_HAS_IMAGE`=(
-				select count(1)
-				from `".self::conf_get('table_name')."`
-				where
-					`REMOTE_ID`='".$remote_id."'
-					and `REMOTE_TABLE`='".$remote_table."'
-			)
-		where `ID`='".$remote_id."'
-		limit 1;
-	";
-	$db = DB::getDB();
-	$res = $db->query( $sql );
-	$affected = $db->affected_rows();
-}
+				// convert image if selected option
+				if ($sqlObj['DEST']) {
+					$options_conf = self::conf_get_option_conf($remote_table, $sqlObj['DEST']);
+					if (!empty($options_conf)) {
+						$max_width  = V::get('max_width',  0, $options_conf, 'int');
+						$max_height = V::get('max_height', 0, $options_conf, 'int');
+						if ($max_height > 0 && $max_width > 0) {
+							$imBlob = self::readImageBlobFromFile($req_file_data['tmp_name'], $sqlObj['TYPE']);
+							$sqlObj['IMAGE'] = self::resizeImageFromBlob($imBlob, $sqlObj['TYPE'], $max_width, $max_height);
+							list($sqlObj['WIDTH'], $sqlObj['HEIGHT']) = self::getImageGeometryFromBlob($sqlObj['IMAGE']);
+							$sqlObj['SIZE'] = strlen($sqlObj['IMAGE']);
+							$sqlObj['IMAGE'] = addslashes($sqlObj['IMAGE']);
+						}
+					}
+				}
 
-public static function resize_image($file, $w, $h, $crop=FALSE) {
-	// TODO: image type
-	$im = imagecreatefromjpeg($file);
-	return self::resize_image_from_data($im, $w, $h, $crop);
-}
+				$sql_arr = array();
+				foreach ($sqlObj as $key => $val) {
+					$sql_arr["`{$key}`"] = "'{$val}'";
+				}
+				$sql = "insert into `".self::conf_get_table_name()."` (".implode(",", array_keys($sql_arr)).") values (".implode(",", array_values($sql_arr)).") ; ";
 
-public static function resize_image_from_data($im, $w, $h, $crop=FALSE) {
-	if ($w == 0) $w = $h;
-	if ($h == 0) $h = $w;
-	$width = imagesx($im);
-	$height = imagesy($im);
+				$db = DB::getDB();
+				if (!$db->query($sql)) {
+					$errors[] = 'Unable to upload file - sql error';
+				}
 
-	if ($width < $w && $height < $h) {
-		return $im;
+				self::update_remote_table_stat($remote_table, $remote_id);
+			}
+		}
+		else {
+			// if the file is not less than the maximum allowed, print an error
+			$errors[] = 'File exceeds the Maximum File limit';
+		}
+		return $errors;
 	}
 
-	$r = $width / $height;
-	if ($crop) {
-		if ($width > $height) {
-			$width = ceil($width-($width*($r-$w/$h)));
-		} else {
-			$height = ceil($height-($height*($r-$w/$h)));
+	public static function delete_image($id, $remote_table, $remote_id) {// TODO: RM Legacy
+		return self::deleteImage($id, $remote_table, $remote_id);
+	}
+
+	public static function deleteImage($id, $remote_table, $remote_id) {
+		$db = DB::getDB();
+		$sql = "delete from `".self::conf_get_table_name()."`
+			where
+				`ID`='{$id}'
+				and `REMOTE_ID`='{$remote_id}'
+				and `REMOTE_TABLE`='{$remote_table}'
+			limit 1
+		";
+		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">sql delete = ';print_r($sql);echo'</pre>';
+		$db->query($sql);
+		$affected = $db->affected_rows();
+
+		self::update_remote_table_stat($remote_table, $remote_id);
+
+		return $affected;
+	}
+
+	/**
+	 * Updates field ITEM_IMAGE_REMOTE in remote table.
+	 * TODO: check if field exists!
+	 */
+	public static function update_remote_table_stat($remote_table, $remote_id) {// TODO: used only in this file
+		// update stat `ITEM_IMAGE_REMOTE`
+		$sql = "update `{$remote_table}`
+				set `A_HAS_IMAGE`=(
+					select count(1)
+					from `".self::conf_get('table_name')."`
+					where
+						`REMOTE_ID`='{$remote_id}'
+						and `REMOTE_TABLE`='{$remote_table}'
+				)
+			where `ID`='{$remote_id}'
+			limit 1;
+		";
+		$db = DB::getDB();
+		$res = $db->query($sql);
+		$affected = $db->affected_rows();
+	}
+
+	public static function resize_image($file, $w, $h, $crop = FALSE) {
+		// TODO: image type
+		$im = imagecreatefromjpeg($file);
+		return self::resize_image_from_data($im, $w, $h, $crop);
+	}
+
+	public static function resize_image_from_data($im, $w, $h, $crop = FALSE) {
+		if ($w == 0) $w = $h;
+		if ($h == 0) $h = $w;
+		$width = imagesx($im);
+		$height = imagesy($im);
+
+		if ($width < $w && $height < $h) {
+			return $im;
 		}
-		$newwidth = $w;
-		$newheight = $h;
-	} else {
-		if ($w/$h > $r) {
-			$newwidth = $h*$r;
+
+		$r = $width / $height;
+		if ($crop) {
+			if ($width > $height) {
+				$width = ceil($width-($width*($r-$w/$h)));
+			} else {
+				$height = ceil($height-($height*($r-$w/$h)));
+			}
+			$newwidth = $w;
 			$newheight = $h;
 		} else {
-			$newheight = $w/$r;
-			$newwidth = $w;
+			if ($w/$h > $r) {
+				$newwidth = $h*$r;
+				$newheight = $h;
+			} else {
+				$newheight = $w/$r;
+				$newwidth = $w;
+			}
 		}
+		$dst = imagecreatetruecolor($newwidth, $newheight);
+		imagecopyresampled($dst, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
+
+		return $dst;
 	}
-	$dst = imagecreatetruecolor($newwidth, $newheight);
-	imagecopyresampled($dst, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
 
-	return $dst;
-}
+	public static function show_size($size) {// TODO: RM -> moved to showSize
+		return self::showSize($size);
+	}
 
-public static function show_size( $size ) {
-	$ret_unit = 'B';
-	if ($size > 1024 * 1024) {
-		$size = $size / (1024 * 1024);
-		$ret_unit = 'MB';
-	} else if ($size > 1024) {
-		$size = $size / 1024;
-		$ret_unit = 'KB';
+	public static function showSize($size) {
+		$ret_unit = 'B';
+		if ($size > 1024 * 1024) {
+			$size = $size / (1024 * 1024);
+			$ret_unit = 'MB';
+		} else if ($size > 1024) {
+			$size = $size / 1024;
+			$ret_unit = 'KB';
+		}
+		return number_format($size, 2, '.', ' ').''.$ret_unit;
 	}
-	return number_format($size, 2, '.', ' ').''.$ret_unit;
-}
 
 }

+ 256 - 265
SE/se-lib/Filter.php

@@ -1,322 +1,313 @@
 <?php
 
 
-Class Filter {
-
-
-var $args;
-var $args_default;
-var $filters;
-var $labels;
-var $callbacks;
-var $_key;
-var $_storage;// enum('session', 'cookie')
-var $_trash_filtr;// Tree trash
-
-
-/**
- * @param $args - args table: $_GET, $_POST, $_REQUEST, etc
- * @param $key - kay to store values in @storage, if not set then args not saved
- * @param $storage - where to store state - cookie or session, default is cookie
- */
-function __construct($args, $key = null, $storage = 'cookie') {
-	$this->args = $args;
-	$this->args_default = array();
-	$this->filters = array();
-	$this->labels = array();
-	$this->callbacks = array();
-	$this->_key = 'filter-'.$key;
-	$this->_storage = $storage;
-	$this->_init_args();
-	$this->_trash_filtr = null;
-}
-
-
-function get_arg($name) {
-	// try load from @storage and save
-	if (array_key_exists($name, $this->args)) {
-		return $this->args[$name];
-	} else if (array_key_exists($name, $this->args_default)) {
-		return $this->args_default[$name];
+class Filter {
+
+	var $args;
+	var $args_default;
+	var $filters;
+	var $labels;
+	var $callbacks;
+	var $_key;
+	var $_storage;// enum('session', 'cookie')
+	var $_trash_filtr;// Tree trash
+
+	/**
+	 * @param $args - args table: $_GET, $_POST, $_REQUEST, etc
+	 * @param $key - kay to store values in @storage, if not set then args not saved
+	 * @param $storage - where to store state - cookie or session, default is cookie
+	 */
+	function __construct($args, $key = null, $storage = 'cookie') {
+		$this->args = $args;
+		$this->args_default = array();
+		$this->filters = array();
+		$this->labels = array();
+		$this->callbacks = array();
+		$this->_key = 'filter-'.$key;
+		$this->_storage = $storage;
+		$this->_init_args();
+		$this->_trash_filtr = null;
 	}
-	return null;
-}
-
 
-function _init_args() {
-	if (array_key_exists('filtr_clear', $this->args) && $this->args['filtr_clear'] == 1) {
-		$this->args = array();
-	} else {
-		$this->_read_args();
+	public function get_arg($name) {
+		// TODO: allow only keys from $this->filters
+		// try load from @storage and save
+		if (array_key_exists($name, $this->args)) {
+			return $this->args[$name];
+		} else if (array_key_exists($name, $this->args_default)) {
+			return $this->args_default[$name];
+		}
+		return null;
 	}
-}
-
 
-function add_filter($name, $values, $default, $label = '', $callback = null) {
-	$this->filters[$name] = $values;
-	$this->labels[$name] = ($label)? $label : $name;
-	$this->args_default[$name] = $default;
-	if ($callback) $this->callbacks[$name] = $callback;
-}
+	public function setArgs($args) {
+		foreach ($args as $k => $v) {
+			if (!array_key_exists($k, $this->filters)) continue;
+			$this->args[$k] = $v;
+		}
+	}
 
+	private function _init_args() {
+		if (array_key_exists('filtr_clear', $this->args) && $this->args['filtr_clear'] == 1) {
+			$this->args = array();
+		} else {
+			$this->_read_args();
+		}
+	}
 
-function _save_args() {
-	if (!$this->_key) { return; }
-	if ($this->_storage == 'cookie') {
-		$this->_save_args_in_cookie();
-	} else {
-		$this->_save_args_in_session();
+	function add_filter($name, $values, $default, $label = '', $callback = null) {
+		$this->filters[$name] = $values;
+		$this->labels[$name] = ($label)? $label : $name;
+		$this->args_default[$name] = $default;
+		if ($callback) $this->callbacks[$name] = $callback;
 	}
-}
 
+	public function _save_args() {
+		if (!$this->_key) { return; }
+		if ($this->_storage == 'cookie') {
+			$this->_save_args_in_cookie();
+		} else {
+			$this->_save_args_in_session();
+		}
+	}
 
-function _save_args_in_session() {
-	if (!$this->_key) { return; }
+	private function _save_args_in_session() {
+		if (!$this->_key) { return; }
 
-	$save_args = array();
-	foreach ($this->filters as $name => $options) {
-		$arg = (isset($this->args[$name]))? $this->args[$name] : '';
-		if (count($options) == 1 && reset($options) == 'search') {
-			if ($arg != $this->args_default[$name]) {
-				$option = $arg;
-				$save_args[] = ''.urlencode($name).'='.urlencode($option);
-			}
-		} else {
-			foreach($options as $option => $field_name) {
-				if (isset($this->args[$name]) && $this->args[$name] == $option) {
+		$save_args = array();
+		foreach ($this->filters as $name => $options) {
+			$arg = (isset($this->args[$name]))? $this->args[$name] : '';
+			if (count($options) == 1 && reset($options) == 'search') {
+				if ($arg != $this->args_default[$name]) {
+					$option = $arg;
 					$save_args[] = ''.urlencode($name).'='.urlencode($option);
 				}
+			} else {
+				foreach($options as $option => $field_name) {
+					if (isset($this->args[$name]) && $this->args[$name] == $option) {
+						$save_args[] = ''.urlencode($name).'='.urlencode($option);
+					}
+				}
 			}
 		}
-	}
-
-	$save_args = implode(',', $save_args);
-	$_SESSION[$this->_key] = $save_args;
-}
 
+		$save_args = implode(',', $save_args);
+		$_SESSION[$this->_key] = $save_args;
+	}
 
-function _save_args_in_cookie() {
-	if (!$this->_key) { return; }
+	private function _save_args_in_cookie() {
+		if (!$this->_key) { return; }
 
-	$save_args = array();
-	foreach ($this->filters as $name => $options) {
-		$arg = (isset($this->args[$name]))? $this->args[$name] : '';
-		if (count($options) == 1 && reset($options) == 'search') {
-			if ($arg != $this->args_default[$name]) {
-				$option = $arg;
-				$save_args[] = ''.urlencode($name).'='.urlencode($option);
-			}
-		} else {
-			foreach($options as $option => $field_name) {
-				if (isset($this->args[$name]) && $this->args[$name] == $option) {
+		$save_args = array();
+		foreach ($this->filters as $name => $options) {
+			$arg = (isset($this->args[$name]))? $this->args[$name] : '';
+			if (count($options) == 1 && reset($options) == 'search') {
+				if ($arg != $this->args_default[$name]) {
+					$option = $arg;
 					$save_args[] = ''.urlencode($name).'='.urlencode($option);
 				}
+			} else {
+				foreach($options as $option => $field_name) {
+					if (isset($this->args[$name]) && $this->args[$name] == $option) {
+						$save_args[] = ''.urlencode($name).'='.urlencode($option);
+					}
+				}
 			}
 		}
+	//	if ($save_args) {
+			$save_args = implode(',', $save_args);
+			echo'<script type="text/javascript">';echo"
+				(function(){
+					var exdate=new Date()
+						, exdays = 14
+						, c_name='".$this->_key."'
+						, value='".$save_args."'
+					;
+					exdate.setDate(exdate.getDate() + exdays);
+					var c_value=escape(value) + ((exdays==null) ? '' : '; expires='+exdate.toUTCString());
+					document.cookie=c_name + '=' + c_value;
+				})();
+			";echo'</script>';
+	//	}
 	}
-//	if ($save_args) {
-		$save_args = implode(',', $save_args);
-		echo'<script type="text/javascript">';echo"
-			(function(){
-				var exdate=new Date()
-					, exdays = 14
-					, c_name='".$this->_key."'
-					, value='".$save_args."'
-				;
-				exdate.setDate(exdate.getDate() + exdays);
-				var c_value=escape(value) + ((exdays==null) ? '' : '; expires='+exdate.toUTCString());
-				document.cookie=c_name + '=' + c_value;
-			})();
-		";echo'</script>';
-//	}
-}
-
 
-function _read_args($force = false) {
-	if (!$this->_key) { return; }
-	if ($this->_storage == 'cookie') {
-		$this->_read_args_from_cookie($force);
-	} else {
-		$this->_read_args_from_session($force);
+	public function _read_args($force = false) {
+		if (!$this->_key) { return; }
+		if ($this->_storage == 'cookie') {
+			$this->_read_args_from_cookie($force);
+		} else {
+			$this->_read_args_from_session($force);
+		}
 	}
-}
 
-
-function _read_args_from_session($force = false) {
-	if (!$this->_key) { return; }
-	if (!array_key_exists($this->_key, $_SESSION)) { return; }
-	$c_args = explode(',', $_SESSION[$this->_key]);
-//echo'<p>read from session c_args: '.$_SESSION[$this->_key].'</p>';
-	foreach ($c_args as $c_val) {
-		$c_val = explode('=', $c_val);
-		if (count($c_val) != 2) continue;
-		$name = urldecode($c_val[0]);
-		$option = urldecode($c_val[1]);
-		if ($force || !array_key_exists($name, $this->args)) {
-//echo'<p>read from session: '.$name.' / '.$this->args[$name].' / set '.$option.'</p>';
-			$this->args[$name] = $option;
+	private function _read_args_from_session($force = false) {
+		if (!$this->_key) { return; }
+		if (!array_key_exists($this->_key, $_SESSION)) { return; }
+		$c_args = explode(',', $_SESSION[$this->_key]);
+	//echo'<p>read from session c_args: '.$_SESSION[$this->_key].'</p>';
+		foreach ($c_args as $c_val) {
+			$c_val = explode('=', $c_val);
+			if (count($c_val) != 2) continue;
+			$name = urldecode($c_val[0]);
+			$option = urldecode($c_val[1]);
+			if ($force || !array_key_exists($name, $this->args)) {
+	//echo'<p>read from session: '.$name.' / '.$this->args[$name].' / set '.$option.'</p>';
+				$this->args[$name] = $option;
+			}
 		}
 	}
-}
 
-
-/**
- * Read args from cookie.
- */
-function _read_args_from_cookie($force = false) {
-	if (!$this->_key) { return; }
-	if (!array_key_exists($this->_key, $_COOKIE)) { return; }
-	$c_args = explode(',', $_COOKIE[$this->_key]);
-	foreach ($c_args as $c_val) {
-		$c_val = explode('=', $c_val);
-		if (count($c_val) != 2) continue;
-		$name = urldecode($c_val[0]);
-		$option = urldecode($c_val[1]);
-		if ($force || !array_key_exists($name, $this->args)) {
-			$this->args[$name] = $option;
+	/**
+	 * Read args from cookie.
+	 */
+	private function _read_args_from_cookie($force = false) {
+		if (!$this->_key) { return; }
+		if (!array_key_exists($this->_key, $_COOKIE)) { return; }
+		$c_args = explode(',', $_COOKIE[$this->_key]);
+		foreach ($c_args as $c_val) {
+			$c_val = explode('=', $c_val);
+			if (count($c_val) != 2) continue;
+			$name = urldecode($c_val[0]);
+			$option = urldecode($c_val[1]);
+			if ($force || !array_key_exists($name, $this->args)) {
+				$this->args[$name] = $option;
+			}
 		}
 	}
-}
 
+	/**
+	 * Print form fields. Must be inside <form> tag.
+	 */
+	public function show_filters() {
+		// read args from cookie if exists
+		$selected_defaults = true;
 
-/**
- * Print form fields. Must be inside <form> tag.
- */
-function show_filters() {
-	// read args from cookie if exists
-	$selected_defaults = true;
-
-	// bug fix in browser, run onclick action on first submit/image/button element in html code
-	echo'<nobr style="float:right;margin:-9999px 0 0 -9999px;">';
-		echo'<input type="submit" value="'."submit".'" />';
-	echo'</nobr>';
-
-	// show trash if exists
-	echo $this->show_trash();
-
-	// show filters
-	foreach ($this->filters as $name => $options) {
-		$out = new stdClass();
-		$out->cls = '';// class
-		$out->cnt = '';// content
-
-		$selected_option = (isset($this->args[$name]))? $this->args[$name] : $this->args_default[$name];
-		if (count($options) == 1 && reset($options) == 'search') {
-			$size = strlen($selected_option); $size = ($size < 4)? 4 : $size + 2;// size min 4
-			$out->cnt .= '<input type="text" name="'.$name.'" value="'.$selected_option.'" class="i" size="'.$size.'" />';
-			if ($selected_option != $this->args_default[$name]) {
-				$selected_defaults = false;
-				$out->cls = 'active';
-				//echo' <input type="submit" value="'."x".'" onclick="'."this.form.".$name.".value='';".'" title="'."Usuń".'" />';
-				// po kliknięciu ENTER w polu wymuszało usuwanie zawartości pola - 1st submit btn in form
-				$out->cnt .= '<input type="button" value="'."x".'" onclick="'."this.form.".$name.".value='';this.form.submit();".'" title="'."Usuń".'" />';
-			}
-			//$out->cnt .= '<input type="submit" value="'."Szukaj".'" />';
-			$out->cnt .= '<input type="image" src="' . "icon/search.png" . '" ale="'."Szukaj".'" title="'."Szukaj".'" />';
-		}
-		else if (count($options) == 2) {// 2 opcje do wyboru to button
-			$selected_button = $selected_option;
-			if (!array_key_exists($selected_button, $options)) {
-				$selected_button = $this->args_default[$name];
-			}
-			if ($selected_button != $this->args_default[$name]) {
-				$selected_defaults = false;
-				$out->cls = 'active';
-			}
-			foreach ($options as $option => $val) {
-				if ($selected_button != $option) {
-					$out->cnt .= '<input type="submit" name="'.$name.'" value="'.$option.'" />';
+		// bug fix in browser, run onclick action on first submit/image/button element in html code
+		echo'<nobr style="float:right;margin:-9999px 0 0 -9999px;">';
+			echo'<input type="submit" value="'."submit".'" />';
+		echo'</nobr>';
+
+		// show trash if exists
+		echo $this->show_trash();
+
+		// show filters
+		foreach ($this->filters as $name => $options) {
+			$out = new stdClass();
+			$out->cls = '';// class
+			$out->cnt = '';// content
+
+			$selected_option = (isset($this->args[$name]))? $this->args[$name] : $this->args_default[$name];
+			if (count($options) == 1 && reset($options) == 'search') {
+				$size = strlen($selected_option); $size = ($size < 4)? 4 : $size + 2;// size min 4
+				$out->cnt .= '<input type="text" name="'.$name.'" value="'.$selected_option.'" class="i" size="'.$size.'" />';
+				if ($selected_option != $this->args_default[$name]) {
+					$selected_defaults = false;
+					$out->cls = 'active';
+					//echo' <input type="submit" value="'."x".'" onclick="'."this.form.".$name.".value='';".'" title="'."Usuń".'" />';
+					// po kliknięciu ENTER w polu wymuszało usuwanie zawartości pola - 1st submit btn in form
+					$out->cnt .= '<input type="button" value="'."x".'" onclick="'."this.form.".$name.".value='';this.form.submit();".'" title="'."Usuń".'" />';
 				}
+				//$out->cnt .= '<input type="submit" value="'."Szukaj".'" />';
+				$out->cnt .= '<input type="image" src="' . "icon/search.png" . '" ale="'."Szukaj".'" title="'."Szukaj".'" />';
 			}
-		}
-		else {// ponad 2 opcje to select
-			$out->cnt .= '<select name="'.$name.'" onchange="this.form.submit();">';
-			if ($selected_option != $this->args_default[$name]) {
-				$selected_defaults = false;
-				$out->cls = 'active';
+			else if (count($options) == 2) {// 2 opcje do wyboru to button
+				$selected_button = $selected_option;
+				if (!array_key_exists($selected_button, $options)) {
+					$selected_button = $this->args_default[$name];
+				}
+				if ($selected_button != $this->args_default[$name]) {
+					$selected_defaults = false;
+					$out->cls = 'active';
+				}
+				foreach ($options as $option => $val) {
+					if ($selected_button != $option) {
+						$out->cnt .= '<input type="submit" name="'.$name.'" value="'.$option.'" />';
+					}
+				}
 			}
-			foreach ($options as $option => $field_name) {
-				$sel = ($selected_option == $option)? 'selected' : '';
-				$out->cnt .= '<option value="'.$option.'" '.$sel.'>'.$option.'</option>';
+			else {// ponad 2 opcje to select
+				$out->cnt .= '<select name="'.$name.'" onchange="this.form.submit();">';
+				if ($selected_option != $this->args_default[$name]) {
+					$selected_defaults = false;
+					$out->cls = 'active';
+				}
+				foreach ($options as $option => $field_name) {
+					$sel = ($selected_option == $option)? 'selected' : '';
+					$out->cnt .= '<option value="'.$option.'" '.$sel.'>'.$option.'</option>';
+				}
+				$out->cnt .= '</select>';
 			}
-			$out->cnt .= '</select>';
+
+			echo' <nobr'.(($out->cls)? ' class="'.$out->cls.'"' : '').'>';
+				echo $this->labels[$name];
+				echo $out->cnt;
+			echo'</nobr>';
+			echo $this->separator();
+			unset($out);
 		}
 
-		echo' <nobr'.(($out->cls)? ' class="'.$out->cls.'"' : '').'>';
-			echo $this->labels[$name];
-			echo $out->cnt;
-		echo'</nobr>';
-		echo $this->separator();
-		unset($out);
+		if (!$selected_defaults) {
+			echo'<nobr>';
+			echo'<input type="hidden" name="filtr_clear" value="0" />';
+			echo' <input type="button" value="'."Wyczyść filtr".'" onclick="this.form.filtr_clear.value=1;this.form.submit()" /> ';
+			echo'</nobr>';
+		}
+		$this->_save_args();
 	}
 
-	if (!$selected_defaults) {
-		echo'<nobr>';
-		echo'<input type="hidden" name="filtr_clear" value="0" />';
-		echo' <input type="button" value="'."Wyczyść filtr".'" onclick="this.form.filtr_clear.value=1;this.form.submit()" /> ';
-		echo'</nobr>';
+	public function set_trash($filtr_key = '', $value = 0) {
+		$this->_trash_filtr = array('filtr_key'=>$filtr_key, 'value'=>$value);
 	}
-	$this->_save_args();
-}
-
-
-function set_trash($filtr_key = '', $value = 0) {
-	$this->_trash_filtr = array('filtr_key'=>$filtr_key, 'value'=>$value);
-}
 
+	public function is_trash() {
+		if ($this->_trash_filtr === null) {
+			return false;
+		}
 
-function is_trash() {
-	if ($this->_trash_filtr === null) {
+		$trash_filtr_key = $this->_trash_filtr['filtr_key'];
+		$trash_filtr_value = $this->_trash_filtr['value'];
+		$filtr_value = $this->get_arg($trash_filtr_key);
+		if ($filtr_value === null) {
+			return false;
+		}
+		if ($filtr_value == $trash_filtr_value) {
+			return true;
+		}
 		return false;
 	}
 
-	$trash_filtr_key = $this->_trash_filtr['filtr_key'];
-	$trash_filtr_value = $this->_trash_filtr['value'];
-	$filtr_value = $this->get_arg($trash_filtr_key);
-	if ($filtr_value === null) {
-		return false;
-	}
-	if ($filtr_value == $trash_filtr_value) {
-		return true;
-	}
-	return false;
-}
+	public function show_trash() {
+		$out = '';
+		if ($this->_trash_filtr === null) {
+			return $out;
+		}
 
+		$trash_filtr_key = $this->_trash_filtr['filtr_key'];
+		$trash_filtr_value = $this->_trash_filtr['value'];
+		$filtr_value = $this->get_arg($trash_filtr_key);
+		if ($filtr_value === null) {// filtr not exists, TODO: throw error?
+			return $out;
+		}
+		$out .= '<nobr>';
+			if ($this->is_trash()) {
+				//echo App::link("Drzewo", array('task'=>App::get_task()), array('ico'=>'trash_out.gif', 'title'=>'Wroc do drzewa'));
+				$trash_ico = 'icon/trash_out.gif';
+				$onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='';this.form.submit();".'"';
+				$out .= '<input type="image" src="'.$trash_ico.'" value="'."Drzewo".'" class="i"'.$onclick.' title="'."Wroc do drzewa".'" />';
+			} else {
+				//echo App::link("Kosz", array('task'=>App::get_task(), 'filtr_id'=>"-1"), array('ico'=>'trash.gif', 'title'=>'Kosz'));
+				$trash_ico = 'icon/trash.gif';
+				$onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='".$trash_filtr_value."';this.form.submit();".'"';
+				$out .= '<input type="image" src="'.$trash_ico.'" value="'."Kosz".'" class="i"'.$onclick.' title="'."Kosz".'" />';
+			}
+		$out .= '</nobr>';
+		$out .= $this->separator();
 
-function show_trash() {
-	$out = '';
-	if ($this->_trash_filtr === null) {
 		return $out;
 	}
 
-	$trash_filtr_key = $this->_trash_filtr['filtr_key'];
-	$trash_filtr_value = $this->_trash_filtr['value'];
-	$filtr_value = $this->get_arg($trash_filtr_key);
-	if ($filtr_value === null) {// filtr not exists, TODO: throw error?
-		return $out;
+	function separator() {
+		return '<div class="btnseparator"></div>';// separator
 	}
-	$out .= '<nobr>';
-		if ($this->is_trash()) {
-			//echo App::link("Drzewo", array('task'=>App::get_task()), array('ico'=>'trash_out.gif', 'title'=>'Wroc do drzewa'));
-			$trash_ico = 'icon/trash_out.gif';
-			$onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='';this.form.submit();".'"';
-			$out .= '<input type="image" src="'.$trash_ico.'" value="'."Drzewo".'" class="i"'.$onclick.' title="'."Wroc do drzewa".'" />';
-		} else {
-			//echo App::link("Kosz", array('task'=>App::get_task(), 'filtr_id'=>"-1"), array('ico'=>'trash.gif', 'title'=>'Kosz'));
-			$trash_ico = 'icon/trash.gif';
-			$onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='".$trash_filtr_value."';this.form.submit();".'"';
-			$out .= '<input type="image" src="'.$trash_ico.'" value="'."Kosz".'" class="i"'.$onclick.' title="'."Kosz".'" />';
-		}
-	$out .= '</nobr>';
-	$out .= $this->separator();
-
-	return $out;
-}
-
-
-function separator() {
-	return '<div class="btnseparator"></div>';// separator
-}
-
 
 }

+ 145 - 0
SE/se-lib/FilterFactory.php

@@ -0,0 +1,145 @@
+<?php
+
+Lib::loadClass('Filter');
+
+class FilterFactory {
+
+	public static function build($tbl) {
+		Lib::loadClass('Filter');
+		$args = array();
+		$tree_filter = new Filter($args, $tbl, 'session');
+
+		// TODO: add trigger: on clear all filters - remove cookie, on tree key
+		//$tree_filter->
+
+		if ($tbl == 'CRM_PROCES') {
+			{// filtry
+				$filtr = array();
+				if (User::hasAccess('procesy_admin')) { // filtr_edit, only for admins
+					$filtr = array();
+					$filtr['TAK'] = '1';
+					$filtr['NIE'] = '0';
+					$tree_filter->add_filter('filtr_edit', $filtr, 'NIE', 'Edytuj');
+				}
+				{ // filtr_drzewo - TODO: czy uzywane?
+					$filtr = array();
+					$filtr['ZWIN'] = '0';
+					$filtr['ROZWIN'] = '1';
+					//TODO: add js, onclick - remove cookie to hide tree
+					$tree_filter->add_filter('filtr_drzewo', $filtr, 'ROZWIN', 'Drzewo');
+				}
+				{ // filtr_procesy
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_procesy', $filtr, '-', 'Procesy');
+				}
+				{ // filtr_zasoby
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_zasoby', $filtr, '-', 'Zasoby');
+				}
+				{ // filtr_opis
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_opis', $filtr, '-', 'Opisy');
+				}
+				{ // filtr_img
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_img', $filtr, '-', 'IMG');
+				}
+				{ // filtr_id
+					$filtr = array('search');
+					$tree_filter->add_filter('filtr_id', $filtr, '', 'Filtruj ID');
+				}
+				{ // filtr_search_id
+					$filtr = array('search');
+					// TODO: add js search without page reload, add #TREE{ID}
+					$tree_filter->add_filter('filtr_search_id', $filtr, '', 'Wyszukaj ID');
+				}
+				{ // filtr_view
+					$filtr = array();
+					$filtr['NOWY'] = '1';
+					$filtr['STARY'] = '0';
+					$tree_filter->add_filter('filtr_view', $filtr, 'NOWY', 'Widok');
+				}
+				{ // filtr_ajax
+					$filtr = array();
+					$filtr['NIE'] = '0';
+					$filtr['TAK'] = '1';
+					$tree_filter->add_filter('filtr_ajax', $filtr, 'TAK', 'Ajax');
+				}
+			}
+		}
+		else if ($tbl == 'CRM_LISTA_ZASOBOW') {
+			{// filtry
+				$filtr = array();
+				if (User::hasAccess('procesy_admin')) { // filtr_edit, only for admins
+					$filtr = array();
+					$filtr['TAK'] = '1';
+					$filtr['NIE'] = '0';
+					$tree_filter->add_filter('filtr_edit', $filtr, 'NIE', 'Edytuj');
+				}
+				{ // filtr_drzewo
+					$filtr = array();
+					$filtr['ZWIN'] = '0';
+					$filtr['ROZWIN'] = '1';
+					$tree_filter->add_filter('filtr_drzewo', $filtr, 'ZWIN', 'Drzewo');
+				}
+				{ // filtr_ob
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_ob', $filtr, '-', 'OB');
+				}
+				{ // filtr_img
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_img', $filtr, '-', 'IMG');
+				}
+				{ // filtr_opis
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_opis', $filtr, '-', 'Opisy');
+				}
+				{ // filtr_ids
+					$filtr = array();
+					$filtr['-'] = '0';
+					$filtr['+'] = '1';
+					$tree_filter->add_filter('filtr_ids', $filtr, '-', 'IDS');
+				}
+				{ // filtr_id
+					$filtr = array('search');
+					$tree_filter->add_filter('filtr_id', $filtr, '', 'Filtruj ID');
+				}
+				{ // filtr_search_id
+					$filtr = array('search');
+					$tree_filter->add_filter('filtr_search_id', $filtr, '', 'Wyszukaj ID');
+				}
+				{ // filtr_view
+					$filtr = array();
+					$filtr['NOWY'] = '1';
+					$filtr['STARY'] = '0';
+					$tree_filter->add_filter('filtr_view', $filtr, 'NOWY', 'Widok');
+				}
+				{ // filtr_ajax
+					$filtr = array();
+					$filtr['TAK'] = '1';
+					$filtr['NIE'] = '0';
+					$tree_filter->add_filter('filtr_ajax', $filtr, 'TAK', 'Ajax');
+				}
+			}
+		}
+		else {
+			// unknown table
+		}
+		return $tree_filter;
+	}
+
+}

+ 282 - 70
SE/se-lib/ProcesMenu.php

@@ -4,6 +4,11 @@ require_once dirname(__FILE__) . '/' . 'Lib.php';
 Lib::loadClass('V');
 Lib::loadClass('User');
 Lib::loadClass('ProcesTestyHelper');
+Lib::loadClass('TypespecialVariable');
+Lib::loadClass('UsersHelper');
+Lib::loadClass('DB');
+Lib::loadClass('UserBookmarks');
+Lib::loadClass('FilterFactory');
 
 class ProcesMenu {
 
@@ -30,7 +35,6 @@ class ProcesMenu {
 			}
 		}
 
-		Lib::loadClass('UsersHelper');
 		$this->_acl = UsersHelper::getUserAcl($this->_user_id);
 		if (!$this->_acl) {
 			die('Error Acl');
@@ -168,21 +172,11 @@ class ProcesMenu {
 		$this->menuAction();
 		$userAcl = User::getAcl();
 
-		$map = $this->_acl->getUsedProcesMap();
-		$menu_to_show = array_keys($map);
-		if (empty($menu_to_show)) {
+		$procesy_init_ids = $this->_acl->getUsedProcesInitList();
+		if (empty($procesy_init_ids)) {
 			echo '<p>' . "Brak przypisanych procesów." . '</p>';
 			return;
 		}
-
-		$procesy_init_ids = array();
-		Lib::loadClass('DB');
-		$db = DB::getDB();
-		$sql = "select `ID`,`DESC` from `CRM_PROCES` where `TYPE`='PROCES_INIT' and `ID` in (".implode(",", $menu_to_show).") ";
-		$res = $db->query($sql);
-		while ($r = $db->fetch($res)) {
-			$procesy_init_ids[$r->ID] = $r->DESC;
-		}
 		?>
 		<style type="text/css">
 .tbl-wyniki-testow {}
@@ -342,7 +336,6 @@ class ProcesMenu {
 /*
  * $_SESSION['USER_PROFILE'][section][key] = val;
  */
-		Lib::loadClass('UserBookmarks');
 		$userBookmarks = UserBookmarks::getInstance();
 
 		$bookmarksJson = array();
@@ -359,6 +352,28 @@ class ProcesMenu {
 		$userGroupIdsCSV = User::getGroupsIds();
 		$userGroupIdsCSV = implode(',', $userGroupIdsCSV);
 
+		$typeSpecialUserId = null;
+		if (User::isAdmin()) {
+			$typeSpecialUserId = TypespecialVariable::getInstance(-1, '__USER_ID');
+		}
+		$typeSpecialZasob = TypespecialVariable::getInstance(-1, '__ZASOB');
+
+		$treeZasobyFilter = FilterFactory::build('CRM_LISTA_ZASOBOW');
+		$lastZasobyFiltrIds = $treeZasobyFilter->get_arg('filtr_id');
+
+		$userProcesIdsCSV = $this->_acl->getUsedProcesInitIds();
+		$userProcesIdsCSV = implode(',', $userProcesIdsCSV);
+
+		$typeSpecialProces = TypespecialVariable::getInstance(-1, '__PROCES');
+
+		$treeProcesyFilter = FilterFactory::build('CRM_PROCES');
+		$lastProcesyFiltrIds = $treeProcesyFilter->get_arg('filtr_id');
+
+		$menuProcesViewedTblId = 0;
+		if ('VIEWTABLE_AJAX' == V::get('MENU_INIT', '', $_REQUEST)) {
+			$menuProcesViewedTblId = V::get('ZASOB_ID', 0, $_REQUEST, 'int');
+		}
+
 		?>
 <div id="SE-menu" class="navbar navbar-inverse" style="position: static;">
 	<div class="navbar-inner">
@@ -394,13 +409,164 @@ class ProcesMenu {
 							<?php endforeach; ?>
 						</ul>
 					</li>
-					<li<?php if ($active == 'procesy') echo ' class="active"'; ?>><a href="procesy5.php?task=CRM_PROCES" title="Wyswietlenie procesow">Procesy</a></li>
-					<li class="dropdown <?php if ($active == 'zasoby') echo "active"; ?>">
-						<a id="ProcesMenuZasobDropdownLink" href="#" class="dropdown-toggle" data-toggle="dropdown">Zasoby <b class="caret"></b></a>
+					<li class="dropdown <?php if ($active == 'procesy') echo "active"; ?>">
+						<a id="ProcesMenuProcesDropdownLink" href="#" class="dropdown-toggle" data-toggle="dropdown">Procesy <b class="caret"></b></a>
 						<ul class="dropdown-menu">
+							<?php if (!empty($lastProcesyFiltrIds)) : ?>
+								<li class="nav-header"><nobr>Wróć do ostatniego wyszukiwania:</nobr></li>
+								<li>
+									<a href="procesy5.php?task=CRM_PROCES<?php echo "&filtr_id={$lastProcesyFiltrIds}&filtr_ids=%2B&filtr_ob=%2B&filtr_img=%2B";  ?>"><?php
+											//echo $lastProcesyFiltrIdsLabels;
+											if (!empty($lastProcesyFiltrIds)) {
+												$lastProcesyFiltrIds = explode(',', $lastProcesyFiltrIds);
+												$labels = array();
+												$labelsLimit = 4;
+												$labelsInd = 0;
+												foreach ($lastProcesyFiltrIds as $lastFltr) {
+													$labels[] = '<span class="badge badge-inverse">' . $lastFltr . '</span>';
+													if (++$labelsInd >= $labelsLimit) {
+														$labels[] = '...';
+														break;
+													}
+												}
+												$lastProcesyFiltrIdsLabels = implode(' ', $labels);
+											}
+											echo $lastProcesyFiltrIdsLabels;
+										?></a>
+								</li>
+								<li class="divider"></li>
+							<?php endif; ?>
+							<?php if (!empty($userProcesIdsCSV)) : ?>
+								<li>
+									<a href="procesy5.php?task=CRM_PROCES<?php echo "&filtr_id={$userProcesIdsCSV}&filtr_ids=%2B&filtr_ob=%2B&filtr_img=%2B";  ?>" title="Moje Procesy">Moje Procesy</a>
+								</li>
+							<?php endif; ?>
+							<?php if ($menuProcesViewedTblId > 0) : ?>
+								<li>
+									<a href="index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=PROCES_FOR_TABLE&tblId=<?php echo $menuProcesViewedTblId; ?>">Procesy dla aktualnie przeglądanej tabeli</a>
+								</li>
+							<?php endif; ?>
 							<li>
-								<a href="procesy5.php?task=CRM_LISTA_ZASOBOW<?php echo "&filtr_id={$userGroupIdsCSV}&filtr_ids=%2B&filtr_ob=%2B&filtr_img=%2B";  ?>" title="Moje Zasoby">Moje Zasoby</a>
+								<a href="procesy5.php?task=CRM_PROCES&filtr_id=" title="Wyświetlenie drzewa procesó">Wszystkie Procesy</a>
+							</li>
+
+							<li class="divider"></li>
+							<li class="nav-header"><nobr>Wyszukaj:</nobr></li>
+								<?php if (!$typeSpecialProces) : ?>
+									<li>
+										<div class="alert alert-error">Brak typespecial __PROCES</div>
+									</li>
+								<?php else : ?>
+									<li>
+										<form id="ProcesMenuProcesFrm" action="procesy5.php" method="GET" style="padding:0 20px">
+											<input type="hidden" name="task" value="CRM_PROCES">
+											<?php
+												$fldName = 'ProcesMenu__Proces_filtr_id';
+												$fldParams = array();
+												$fldParams['allowCreate'] = false;
+												$fldParams['ajaxDataUrlBase'] = "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=TYPESPECIAL&fld={$fldName}";
+												$fldParams['placeholder'] = 'Szukaj...';
+												$fldParams['formFieldName'] = 'filtr_id';
+												//$fldParams['ajaxDataUrlBase'] .= "&DBG_TS=3";
+												echo $typeSpecialProces->showFormItem($tblID = -1, $fldName, $selValue = '', $fldParams);
+											?>
+											<input class="btn btn-mini btn-primary" type="submit" value="Wybierz" />
+											<input class="pull-right btn btn-mini btn-default" type="submit" id="ProcesMenuProcesFltrAdd" value="Dodaj do filtra" />
+											<script>
+jQuery(document).ready(function() {
+	if ('procesy5.php' === window.location.pathname.substr(-12)
+			&& window.location.search.search('task=CRM_PROCES') > 0
+			&& window.location.search.search('&filtr_id=') > 0
+		 ) {
+		jQuery('#ProcesMenuProcesFltrAdd').on('click', function(e) {
+			var frm = jQuery(this).get(0).form;
+			var fldNode = frm['<?php echo $fldParams['formFieldName']; ?>'],
+				fltrId = '';
+			if (fldNode && '' != fldNode.value) {
+				fltrId = fldNode.value;
+			} else {
+				return;
+			}
+			var pos = 0, fltrIds = '';
+			if ('procesy5.php' === window.location.pathname.substr(-12)
+					&& window.location.search.search('task=CRM_PROCES') > 0
+					&& (pos = window.location.search.search('&filtr_id=')) > 0
+				 ) {
+				pos += 10;
+				fltrIds = window.location.search.substr(pos);
+				if ((pos = fltrIds.search('&')) > 0) {
+					fltrIds = fltrIds.substr(0, pos);
+				}
+				if (fltrIds) {
+					fltrIds = decodeURIComponent(fltrIds);
+					fltrIds += ',' + fltrId;
+					if (fldNode.selectize) {
+						fldNode.selectize.addOption({id: fltrIds, name: fltrIds});
+						fldNode.selectize.setValue(fltrIds, true);
+					}
+				}
+			}
+		});
+	} else {
+		jQuery('#ProcesMenuProcesFltrAdd').hide();
+	}
+
+	jQuery('#ProcesMenuProcesFrm').on('submit', function(e) {
+		var frm = jQuery(this).get(0),
+				fldNode = frm['<?php echo $fldParams['formFieldName']; ?>'];
+		if (fldNode && '' != fldNode.value) {
+			return true;
+		} else {
+			return false;
+		}
+	});
+	jQuery('#ProcesMenuProcesDropdownLink').on('click', function(e) {
+		setTimeout(function(){
+			jQuery('#ts-<?php echo $fldName; ?>')
+				.next('.selectize-control')
+				.find('input:first')
+				.focus();
+		}, 200);
+	});
+});
+											</script>
+										</form>
 							</li>
+								<?php endif; ?>
+						</ul>
+					</li>
+					<li class="dropdown <?php if ($active == 'zasoby') echo "active"; ?>">
+						<a id="ProcesMenuZasobDropdownLink" href="#" class="dropdown-toggle" data-toggle="dropdown">Zasoby <b class="caret"></b></a>
+						<ul class="dropdown-menu">
+							<?php if (!empty($lastZasobyFiltrIds)) : ?>
+								<li class="nav-header"><nobr>Wróć do ostatniego wyszukiwania:</nobr></li>
+								<li>
+									<a href="procesy5.php?task=CRM_LISTA_ZASOBOW<?php echo "&filtr_id={$lastZasobyFiltrIds}&filtr_ids=%2B&filtr_ob=%2B&filtr_img=%2B";  ?>"><?php
+											//echo $lastZasobyFiltrIdsLabels;
+											if (!empty($lastZasobyFiltrIds)) {
+												$lastZasobyFiltrIds = explode(',', $lastZasobyFiltrIds);
+												$labels = array();
+												$labelsLimit = 4;
+												$labelsInd = 0;
+												foreach ($lastZasobyFiltrIds as $lastFltr) {
+													$labels[] = '<span class="badge badge-inverse">' . $lastFltr . '</span>';
+													if (++$labelsInd >= $labelsLimit) {
+														$labels[] = '...';
+														break;
+													}
+												}
+												$lastZasobyFiltrIdsLabels = implode(' ', $labels);
+											}
+											echo $lastZasobyFiltrIdsLabels;
+										?></a>
+								</li>
+								<li class="divider"></li>
+							<?php endif; ?>
+							<?php if (!empty($userGroupIdsCSV)) : ?>
+								<li>
+									<a href="procesy5.php?task=CRM_LISTA_ZASOBOW<?php echo "&filtr_id={$userGroupIdsCSV}&filtr_ids=%2B&filtr_ob=%2B&filtr_img=%2B";  ?>" title="Moje Zasoby">Moje Zasoby</a>
+								</li>
+							<?php endif; ?>
 							<?php if ('VIEWTABLE_AJAX' == V::get('MENU_INIT', '', $_REQUEST)) : ?>
 								<li>
 									<a href="procesy5.php?task=CRM_LISTA_ZASOBOW<?php if(!empty($_REQUEST['ZASOB_ID'])) echo "&filtr_id={$_REQUEST['ZASOB_ID']}&filtr_ids=%2B&filtr_ob=%2B";  ?>" title="Struktura aktualnie przeglądanej tabeli">Struktura aktualnie przeglądanej tabeli</a>
@@ -409,41 +575,90 @@ class ProcesMenu {
 							<li>
 								<a href="procesy5.php?task=CRM_LISTA_ZASOBOW&filtr_id=" title="Wyświetlenie drzewa zasobów">Wszystkie Zasoby</a>
 							</li>
-							<li>
-								<from id="ProcesMenuZasobSearchFrm" class="form-search" method="GET" action="procesy5.php">
-									<input type="hidden" name="task" value="CRM_LISTA_ZASOBOW">
-									<div class="input-append" style="padding:2px 6px">
-										<input id="ProcesMenuZasobSearchInput" type="text" name="filtr_id" class="span2 search-query" placeholder="Nr zasobu">
-										<input id="ProcesMenuZasobSearchSubmit" type="submit" class="btn" value="Szukaj" />
-									</div>
-								</from>
-								<script>
-function procesMenuZasobSearchGo() {
-	var id = jQuery('#ProcesMenuZasobSearchInput').val();
-	if ('' !== id) {
-		window.location.href = window.location.protocol + '//' + window.location.host + window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/')) + '/procesy5.php?task=CRM_LISTA_ZASOBOW&filtr_id=' + id;
-	}
-}
+
+							<li class="divider"></li>
+							<li class="nav-header"><nobr>Wyszukaj:</nobr></li>
+								<?php if (!$typeSpecialZasob) : ?>
+									<li>
+										<div class="alert alert-error">Brak typespecial __ZASOB</div>
+									</li>
+								<?php else : ?>
+									<li>
+										<form id="ProcesMenuZasobFrm" action="procesy5.php" method="GET" style="padding:0 20px">
+											<input type="hidden" name="task" value="CRM_LISTA_ZASOBOW">
+											<?php
+												$fldName = 'ProcesMenu__Zasob_filtr_id';
+												$fldParams = array();
+												$fldParams['allowCreate'] = false;
+												$fldParams['ajaxDataUrlBase'] = "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=TYPESPECIAL&fld={$fldName}";
+												$fldParams['placeholder'] = 'Szukaj...';
+												$fldParams['formFieldName'] = 'filtr_id';
+												//$fldParams['ajaxDataUrlBase'] .= "&DBG_TS=3";
+												echo $typeSpecialZasob->showFormItem($tblID = -1, $fldName, $selValue = '', $fldParams);
+											?>
+											<input class="btn btn-mini btn-primary" type="submit" value="Wybierz" />
+											<input class="pull-right btn btn-mini btn-default" type="submit" id="ProcesMenuZasobFltrAdd" value="Dodaj do filtra" />
+											<script>
 jQuery(document).ready(function() {
-	jQuery('#ProcesMenuZasobSearchInput').on('click', function(e) {
-		return false;
-	});
-	jQuery('#ProcesMenuZasobSearchInput').on('keypress', function(e) {
-		if (e.which == 13) {
-			procesMenuZasobSearchGo();
+	if ('procesy5.php' === window.location.pathname.substr(-12)
+			&& window.location.search.search('task=CRM_LISTA_ZASOBOW') > 0
+			&& window.location.search.search('&filtr_id=') > 0
+		 ) {
+		jQuery('#ProcesMenuZasobFltrAdd').on('click', function(e) {
+			var frm = jQuery(this).get(0).form;
+			var fldNode = frm['<?php echo $fldParams['formFieldName']; ?>'],
+				fltrId = '';
+			if (fldNode && '' != fldNode.value) {
+				fltrId = fldNode.value;
+			} else {
+				return;
+			}
+			var pos = 0, fltrIds = '';
+			if ('procesy5.php' === window.location.pathname.substr(-12)
+					&& window.location.search.search('task=CRM_LISTA_ZASOBOW') > 0
+					&& (pos = window.location.search.search('&filtr_id=')) > 0
+				 ) {
+				pos += 10;
+				fltrIds = window.location.search.substr(pos);
+				if ((pos = fltrIds.search('&')) > 0) {
+					fltrIds = fltrIds.substr(0, pos);
+				}
+				if (fltrIds) {
+					fltrIds = decodeURIComponent(fltrIds);
+					fltrIds += ',' + fltrId;
+					if (fldNode.selectize) {
+						fldNode.selectize.addOption({id: fltrIds, name: fltrIds});
+						fldNode.selectize.setValue(fltrIds, true);
+					}
+				}
+			}
+		});
+	} else {
+		jQuery('#ProcesMenuZasobFltrAdd').hide();
+	}
+
+	jQuery('#ProcesMenuZasobFrm').on('submit', function(e) {
+		var frm = jQuery(this).get(0),
+				fldNode = frm['<?php echo $fldParams['formFieldName']; ?>'];
+		if (fldNode && '' != fldNode.value) {
+			return true;
+		} else {
+			return false;
 		}
 	});
-	jQuery('#ProcesMenuZasobSearchSubmit').on('click', function(e) {
-		procesMenuZasobSearchGo();
-	});
 	jQuery('#ProcesMenuZasobDropdownLink').on('click', function(e) {
 		setTimeout(function(){
-			jQuery('#ProcesMenuZasobSearchInput').focus();
+			jQuery('#ts-<?php echo $fldName; ?>')
+				.next('.selectize-control')
+				.find('input:first')
+				.focus();
 		}, 200);
 	});
 });
-								</script>
+											</script>
+										</form>
 							</li>
+								<?php endif; ?>
 						</ul>
 					</li>
 					<li<?php if ($active == 'obowiazki') echo ' class="active"'; ?>><a href="procesy5.php?task=CRM_WYSWIETL_OBOWIAZKI" title="Wyswietlenie OBOWIAZKOW">Obowiązki</a></li>
@@ -502,32 +717,29 @@ jQuery(document).ready(function() {
 							<li><a href="index.php?LOGIN=PERMS_RELOAD" title="Przeładuj uprawnienia"><i class="icon-refresh"></i> Przeładuj uprawnienia</a></li>
 							<?php if (User::isAdmin()) : ?>
 								<li class="divider"></li>
-								<li class="nav-header">Pokaż testy pracownika:</li>
-								<li>
-									<?php
-										Lib::loadClass('UsersHelper');
-										$users = UsersHelper::get_users_list(null, 100, 0, 'ADM_NAME', 'ASC');
-										$user_sel = array();
-										foreach ($users as $r) {
-											$user_sel [$r->ID] = "{$r->ID}: {$r->ADM_NAME} ({$r->ADM_ACCOUNT}, {$r->EMAIL}, {$r->ADM_PHONE})";
-										}
-
-										if (!empty($user_sel)) {
-											echo '<form action="index.php" method="POST">';
-											echo '<input type="hidden" name="FUNCTION_INIT" value="MENU_SELECT_PROCES">';
-											echo '<input type="hidden" name="_action" value="showMyTests">';
-											echo '<select name="_user_id">';
-											foreach ($user_sel as $k_option => $v_label) {
-												$sel = ($k_option == $this->_user_id)? ' selected="selected"' : '';
-												echo '<option value="' . $k_option . '"' . $sel . '>' . $v_label . '</option>';
-											}
-											echo '</select>';
-											echo ' ';
-											echo '<input type="submit" value="Wybierz" />';
-											echo '</form>';
-										}
-									?>
-								</li>
+								<li class="nav-header"><nobr>Pokaż testy pracownika:</nobr></li>
+								<?php if (!$typeSpecialUserId) : ?>
+									<li>
+										<div class="alert alert-error">Brak typespecial __USERS_ID</div>
+									</li>
+								<?php else : ?>
+									<li>
+										<form action="index.php" method="POST">
+											<input type="hidden" name="FUNCTION_INIT" value="MENU_SELECT_PROCES">
+											<input type="hidden" name="_action" value="showMyTests">
+											<?php
+												$fldName = '_user_id';
+												$fldParams = array();
+												$fldParams['allowCreate'] = false;
+												$fldParams['ajaxDataUrlBase'] = "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=TYPESPECIAL&fld={$fldName}";
+												$fldParams['placeholder'] = 'Szukaj...';
+												//$fldParams['ajaxDataUrlBase'] .= "&DBG_TS=3";
+												echo $typeSpecialUserId->showFormItem($tblID = -1, $fldName, $selValue = '', $fldParams);
+											?>
+											<input class="btn btn-mini btn-warning" type="submit" value="Wybierz" />
+										</form>
+									</li>
+								<?php endif; ?>
 							<?php endif; ?>
 							<li class="divider"></li>
 							<li><a href="index.php?LOGIN=LOGOUT"><i class="icon-off"></i> Wyloguj</a></li>

+ 7 - 0
SE/se-lib/TableAcl.php

@@ -860,6 +860,13 @@ class TableAcl {
 				$value = $type['default'];
 			}
 
+			if (substr($type['type'], 0, 3) == 'int'
+					|| substr($type['type'], 0, 7) == 'tinyint'
+					|| substr($type['type'], 0, 8) == 'smallint'
+			) {
+				$value = intval($type['default']);
+			}
+
 			// fix bug when field is unique and is null allowed: change empty string to null
 			if ($type['null']) {
 				$value = 'NULL';

+ 5 - 2
SE/se-lib/TableAjax.php

@@ -3414,10 +3414,13 @@ jQuery(document).ready(function(){
 					// default value for perms 'W' without 'R' is '*****'
 				}
 				else {
-					$sqlObj->{$vField['name']} = $args["f{$kID}"];
+					$value = $args["f{$kID}"];
 
 					if (empty($args["f{$kID}"]) && strlen($args["f{$kID}"]) == 0) {// fix bug in input type date and value="0000-00-00"
-						$sqlObj->{$vField['name']} = $this->_acl->fixEmptyValueFromUser($kID);
+						$value = $this->_acl->fixEmptyValueFromUser($kID);
+					}
+					if ($record->{$vField['name']} != $value) {
+						$sqlObj->{$vField['name']} = $value;
 					}
 				}
 			}

+ 93 - 0
SE/se-lib/TreeSortChildren.php

@@ -0,0 +1,93 @@
+<?php
+
+class TreeSortChildren {
+
+	public static function sortPrio($id, $tblName, $parentdFldName, $sortDir) {
+		if ($id < 0 || empty($tblName) || empty($parentdFldName) || empty($sortDir)) {
+			return;
+		}
+		$db = DB::getDB();
+		$sql = "select w.`ID`
+				, w.`SORT_PRIO`
+			from `{$tblName}` as w0
+				left join `{$tblName}` as w on(w.`{$parentdFldName}`=w0.`{$parentdFldName}`)
+			where w0.`ID`='{$id}'
+				and w0.`A_STATUS` not in('DELETED')
+				and w.`A_STATUS` not in('DELETED')
+			order by w.`SORT_PRIO` asc, w.`ID` asc
+		";
+		$res = $db->query($sql);
+		$wsk = array();
+		$wskOrder = array();
+		$sort_prio = 0;
+		while ($r = $db->fetch($res)) {
+			$wsk[$r->ID] = $sort_prio;//$r->SORT_PRIO;
+			$wskOrder[$sort_prio] = $r->ID;
+			$sort_prio += 1;
+		}
+		if (empty($wsk)) return;
+		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">wsk ';print_r($wsk);echo'</pre>';
+		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">wsk_order ';print_r($wskOrder);echo'</pre>';
+		$wsk_new = array();
+		if ($sortDir == 'up') {// wskaznik $wsk_id 'w gore' (zmniejsz sort_prio)
+			$old_wsk_id = $wsk[$id];
+			if ($old_wsk_id == 0) return;
+			//echo'zamien "'.$id.'" na "'.$wskOrder[$wsk[$id] - 1 ].'"';
+			$tmp = $wskOrder[$wsk[$id]];
+			$wskOrder[$wsk[$id]] = $wskOrder[$wsk[$id] - 1];
+			$wskOrder[$wsk[$id] - 1] = $tmp;
+		} else if ($sortDir == 'upup') {// wskaznik $wsk_id 'w gore' (zmniejsz sort_prio)
+			$old_wsk_id = $wsk[$id];
+			if ($old_wsk_id == 0) return;
+			$tmp = $wskOrder[$wsk[$id]];
+			$tmp1 = $wskOrder[$wsk[$id] - 1];
+			$tmp2 = $wskOrder[$wsk[$id] - 2];
+			$tmp3 = $wskOrder[$wsk[$id] - 3];
+			$tmp4 = $wskOrder[$wsk[$id] - 4];
+			$tmp5 = $wskOrder[$wsk[$id] - 5];
+			$tmp6 = $wskOrder[$wsk[$id] - 6];
+			$wskOrder[$wsk[$id]] = $tmp1;
+			$wskOrder[$wsk[$id] - 1] = $tmp2;
+			$wskOrder[$wsk[$id] - 2] = $tmp3;
+			$wskOrder[$wsk[$id] - 3] = $tmp4;
+			$wskOrder[$wsk[$id] - 4] = $tmp5;
+			$wskOrder[$wsk[$id] - 5] = $tmp6;
+			$wskOrder[$wsk[$id] - 6] = $tmp;
+		} else if ($sortDir == 'downdown') {// wskaznik $wsk_id 'w gore' (zmniejsz sort_prio)
+			$old_wsk_id = $wsk[$id];
+			if ($old_wsk_id == 0) return;
+			$tmp = $wskOrder[$wsk[$id]];
+			$tmp1 = $wskOrder[$wsk[$id] + 1];
+			$tmp2 = $wskOrder[$wsk[$id] + 2];
+			$tmp3 = $wskOrder[$wsk[$id] + 3];
+			$tmp4 = $wskOrder[$wsk[$id] + 4];
+			$tmp5 = $wskOrder[$wsk[$id] + 5];
+			$tmp6 = $wskOrder[$wsk[$id] + 6];
+			$wskOrder[$wsk[$id]] = $tmp1;
+			$wskOrder[$wsk[$id] + 1] = $tmp2;
+			$wskOrder[$wsk[$id] + 2] = $tmp3;
+			$wskOrder[$wsk[$id] + 3] = $tmp4;
+			$wskOrder[$wsk[$id] + 4] = $tmp5;
+			$wskOrder[$wsk[$id] + 5] = $tmp6;
+			$wskOrder[$wsk[$id] + 6] = $tmp;
+		} else {// wskaznik $wsk_id 'w dol' (zwieksz sort_prio)
+			$old_wsk_id = $wsk[$id];
+			if ($old_wsk_id + 1 == count($wsk)) return;
+			//echo'zamien "'.$id.'" na "'.$wskOrder[$wsk[$id] + 1 ].'"';
+			$tmp = $wskOrder[$wsk[$id]];
+			$wskOrder[$wsk[$id]] = $wskOrder[$wsk[$id] + 1];
+			$wskOrder[$wsk[$id] + 1] = $tmp;
+		}
+		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">2 wsk ';print_r($wsk);echo'</pre>';
+		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">2 wsk_order ';print_r($wskOrder);echo'</pre>';
+		if (empty($wskOrder)) return;
+		foreach ($wskOrder as $k_osrt_prio => $v_wsk_id) {
+			$sql = "update `{$tblName}`
+				set `SORT_PRIO`='{$k_osrt_prio}'
+				where `ID`='{$v_wsk_id}'
+			";
+			$db->query($sql);
+		}
+	}
+
+}

+ 74 - 4
SE/se-lib/TypespecialVariable.php

@@ -25,9 +25,11 @@ class TypespecialVariable extends TypespecialBase {
 			case '__TELBOXES':
 			case '__TELBOXES_NAME':
 			case '__ZASOB':
+			case '__PROCES':
 			case '__COMPANIES':
 			case 'DEFAULT_ACL_GROUP':
 			case 'VERSION_GIT':
+			case '__USER_ID':
 				return new TypespecialVariable($fldID, $fldName);
 				break;
 		}
@@ -65,6 +67,7 @@ class TypespecialVariable extends TypespecialBase {
 			case 'A_CLASSIFIED':
 			case 'DEFAULT_ACL_GROUP':
 			case 'VERSION_GIT':
+			case '__USER_ID':
 				$jsonAllowCreate = 'false';
 				break;
 			default:
@@ -90,7 +93,11 @@ class TypespecialVariable extends TypespecialBase {
 
 		$optionsJson = 'null';
 		$out .= '<div class="typepsecial">';
-		$out .= '<select id="ts-' . $fName . '">';
+		$outPlaceholder = '';
+		if ('' != ($paramPlaceholder = V::get('placeholder', '', $params))) {
+			$outPlaceholder = ' placeholder="' . $paramPlaceholder . '"';
+		}
+		$out .= '<select id="ts-' . $fName . '"' . $outPlaceholder . '>';
 			if (!empty($selValue)) {
 				$tsVal = (!empty($tsValue))? $tsValue : $selValue;
 				//$out .= '<option value="' . $selValue . '" selected="selected" typespecial="'.$tsVal.'">' . $tsVal . '</option>';
@@ -107,8 +114,10 @@ class TypespecialVariable extends TypespecialBase {
 		$ajaxDataUrlBase = "index-ajax.php?_cls=TableAjax&_zasobID={$tblID}&_task=TYPESPECIAL&fldID={$this->fldID}";
 		$ajaxDataUrlBase = V::get('ajaxDataUrlBase', $ajaxDataUrlBase, $params);
 
+		$frmFldName = V::get('formFieldName', $fName, $params);
+
 		$out .= '<script>' . "
-(function(){
+jQuery(document).ready(function(){
 	var fldNode=jQuery('#{$fName}'), tsNode=jQuery('#ts-{$fName}');
 	if (!fldNode && !tsNode) {
 		return;
@@ -119,7 +128,7 @@ class TypespecialVariable extends TypespecialBase {
 	if (fldNode.parent().hasClass('show-last-value')) {
 		fldNode.parent().hide();
 	}
-	tsNode.attr('name', '{$fName}');
+	tsNode.attr('name', '{$frmFldName}');
 	tsNode.attr('tabindex', fldNode.attr('tabindex'));
 	
 
@@ -205,7 +214,7 @@ class TypespecialVariable extends TypespecialBase {
 		}
 	});
 
-})()
+});
 		" . '</script>';
 
 		return $out;
@@ -497,6 +506,30 @@ class TypespecialVariable extends TypespecialBase {
 				if(V::get('DBG_TS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">values (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($values);echo'</pre>';}
 				break;
 			}
+			case '__PROCES': {
+				$db = DB::getDB();
+				$query = trim($query, ' %');
+				$query = $db->_($query);
+				$sqlLimit = 20;
+				$sqlSelectLabel = "concat(z.`TYPE`, ' ', z.`DESC`)";
+				$sqlWhereAdd = "";
+				$sql = "select z.`ID`
+						, {$sqlSelectLabel} as `LABEL`
+					from `CRM_PROCES` as z
+					where z.`A_STATUS` in('NORMAL', 'WAITING')
+						and (z.`DESC` like '%{$query}%' or z.`ID` like '%{$query}%')
+						{$sqlWhereAdd}
+					-- group by z.`DESC`
+					limit {$sqlLimit}
+				";
+				if(V::get('DBG_TS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
+				$res = $db->query($sql);
+				while ($r = $db->fetch($res)) {
+					$values[] = (object)array('id'=>$r->ID, 'param_out'=>$r->LABEL);
+				}
+				if(V::get('DBG_TS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">values (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($values);echo'</pre>';}
+				break;
+			}
 			case '__COMPANIES': {
 				$db = DB::getDB();
 				$query = trim($query, ' %');
@@ -547,6 +580,43 @@ class TypespecialVariable extends TypespecialBase {
 					$values[] = (object)array('id'=>$version, 'param_out'=>$version);
 				}
 			}
+			case '__USER_ID': {
+				$db = DB::getDB();
+				$query = trim($query, ' %');
+				$query = $db->_($query);
+				$sqlLimit = 20;
+				$sqlSelectLabel = array();
+				$sqlSelectLabel[] = 'u.`ADM_NAME`';
+				$sqlSelectLabel[] = "' ('";
+				$sqlSelectLabel[] = 'u.`ADM_ACCOUNT`';
+				$sqlSelectLabel[] = "', '";
+				$sqlSelectLabel[] = 'u.`EMAIL`';
+				$sqlSelectLabel[] = "', '";
+				$sqlSelectLabel[] = 'u.`ADM_PHONE`';
+				$sqlSelectLabel[] = "')'";
+				$sqlSelectLabel = "concat(" . implode(", ", $sqlSelectLabel) . ")";
+
+				$sql = "select u.`ID`
+						, {$sqlSelectLabel} as `LABEL`
+					from `ADMIN_USERS` as u
+					where u.`A_STATUS` in('NORMAL', 'WAITING','MONITOR','WARNING')
+						and u.`EMPLOYEE_TYPE` in('Pracownik','Partner')
+						and (u.`ID` like '%{$query}%'
+							or u.`ADM_ACCOUNT` like '%{$query}%'
+							or u.`ADM_NAME` like '%{$query}%'
+							or u.`ADM_PHONE` like '%{$query}%'
+							or u.`EMAIL` like '%{$query}%'
+						)
+					limit {$sqlLimit}
+				";
+				if(V::get('DBG_TS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
+				$res = $db->query($sql);
+				while ($r = $db->fetch($res)) {
+					$values[] = (object)array('id'=>$r->ID, 'param_out'=>$r->LABEL);
+				}
+				if(V::get('DBG_TS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">values (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($values);echo'</pre>';}
+				break;
+			}
 			default:
 				
 		}

+ 23 - 7
SE/se-lib/UserAcl.php

@@ -159,21 +159,37 @@ class UserAcl {
 		return $usedProcesListIds;
 	}
 
-	public function getUsedProcesInitIds() {// function admin_fetch_CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT() {
-		if (!empty($this->_proces_init_used_ids)) {
-			return $this->_proces_init_used_ids;
+	public function getUsedProcesInitIds($zasobId = 0) {// function admin_fetch_CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT() {
+		if ($zasobId > 0) {
+			$pInitListRaw = $this->getProcesInitList($zasobId);
+			if (!empty($pInitListRaw)) {
+				$pInitListRaw = array_values($pInitListRaw);
+				$pInitListRaw = array_unique($pInitListRaw);
+			}
+			return $pInitListRaw;
+		} else {
+			$usedProcesInitList = $this->getUsedProcesInitList();
+			return array_keys($usedProcesInitList);
+		}
+	}
+
+	public function getUsedProcesInitList() {
+		if (!empty($this->_proces_init_used)) {
+			return $this->_proces_init_used;
 		}
 
 		$map = $this->getUsedProcesMap();
 		if (!empty($map)) {
 			$db = DB::getDB();
-			$sql = "select `ID` from `CRM_PROCES` where `TYPE`='PROCES_INIT' and `ID` in (" . implode(",", array_keys($map)) . ") ";
+			$sql = "select `ID`, `DESC`
+				from `CRM_PROCES`
+				where `TYPE`='PROCES_INIT' and `ID` in (" . implode(",", array_keys($map)) . ") ";
 			$res = $db->query($sql);
-			while ($h = $db->fetch($res)) {
-				$this->_proces_init_used_ids[] = $h->ID;
+			while ($r = $db->fetch($res)) {
+				$this->_proces_init_used[$r->ID] = $r->DESC;
 			}
 		}
-		return $this->_proces_init_used_ids;
+		return $this->_proces_init_used;
 	}
 
 	function old_fixed() {

+ 24 - 3
SE/se-lib/UserStorageDB.php

@@ -480,9 +480,30 @@ class UserStorageDB extends UserStorageBase {
 		$sqlObj->REMOTE_TABLE = 'ADMIN_USERS';
 		$sqlObj->REMOTE_ID = $usrDB->primaryKey;
 		$sqlObj->T_TELBOX_NEIGHBOUR_IN_ID = $telboxID;
-		$rowID = $this->_db->ADD_NEW_OBJ('CRM_AUTH_PROFILE', $sqlObj);
-		if ($rowID > 0) {
-			return true;
+		$sqlObj->A_STATUS = 'NORMAL';
+
+		// uniq key: (ID_ZASOB, REMOTE_ID, REMOTE_TABLE, T_TELBOX_NEIGHBOUR_IN_ID)
+		$sql = "select `ID`
+			from `CRM_AUTH_PROFILE`
+			where `ID_ZASOB`='{$sqlObj->ID_ZASOB}'
+				and `REMOTE_TABLE`='{$sqlObj->REMOTE_TABLE}'
+				and `REMOTE_ID`='{$sqlObj->REMOTE_ID}'
+				and `T_TELBOX_NEIGHBOUR_IN_ID`='{$sqlObj->T_TELBOX_NEIGHBOUR_IN_ID}'
+		";
+		$db = DB::getDB();
+		$res = $db->query($sql);
+		if ($r = $db->fetch($res)) {
+			$sqlObj->ID = $r->ID;
+			$affexted = $this->_db->UPDATE_OBJ('CRM_AUTH_PROFILE', $sqlObj);
+			if ($affexted > 0) {
+				return true;
+			}
+		}
+		else {
+			$rowID = $this->_db->ADD_NEW_OBJ('CRM_AUTH_PROFILE', $sqlObj);
+			if ($rowID > 0) {
+				return true;
+			}
 		}
 		return false;
 	}

+ 0 - 3312
SE/stuff/phpqrcode.php

@@ -1,3312 +0,0 @@
-<?php
-
-/*
- * PHP QR Code encoder
- *
- * This file contains MERGED version of PHP QR Code library.
- * It was auto-generated from full version for your convenience.
- *
- * This merged version was configured to not requre any external files,
- * with disabled cache, error loging and weker but faster mask matching.
- * If you need tune it up please use non-merged version.
- *
- * For full version, documentation, examples of use please visit:
- *
- *    http://phpqrcode.sourceforge.net/
- *    https://sourceforge.net/projects/phpqrcode/
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
- 
-
-/*
- * Version: 1.1.4
- * Build: 2010100721
- */
-
-
-
-//---- qrconst.php -----------------------------
-
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Common constants
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-	// Encoding modes
-	 
-	define('QR_MODE_NUL', -1);
-	define('QR_MODE_NUM', 0);
-	define('QR_MODE_AN', 1);
-	define('QR_MODE_8', 2);
-	define('QR_MODE_KANJI', 3);
-	define('QR_MODE_STRUCTURE', 4);
-
-	// Levels of error correction.
-
-	define('QR_ECLEVEL_L', 0);
-	define('QR_ECLEVEL_M', 1);
-	define('QR_ECLEVEL_Q', 2);
-	define('QR_ECLEVEL_H', 3);
-	
-	// Supported output formats
-	
-	define('QR_FORMAT_TEXT', 0);
-	define('QR_FORMAT_PNG',  1);
-	
-	class qrstr {
-		public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
-			$srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
-		}
-	}	
-
-
-
-//---- merged_config.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Config file, tuned-up for merged verion
- */
-     
-    define('QR_CACHEABLE', false);       // use cache - more disk reads but less CPU power, masks and format templates are stored there
-    define('QR_CACHE_DIR', false);       // used when QR_CACHEABLE === true
-    define('QR_LOG_DIR', false);         // default error logs dir   
-    
-    define('QR_FIND_BEST_MASK', true);                                                          // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code
-    define('QR_FIND_FROM_RANDOM', 2);                                                       // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly
-    define('QR_DEFAULT_MASK', 2);                                                               // when QR_FIND_BEST_MASK === false
-                                                  
-    define('QR_PNG_MAXIMUM_SIZE',  1024);                                                       // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images
-                                                  
-
-
-
-//---- qrtools.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Toolset, handy and debug utilites.
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-    class QRtools {
-    
-        //----------------------------------------------------------------------
-        public static function binarize($frame)
-        {
-            $len = count($frame);
-            foreach ($frame as &$frameLine) {
-                
-                for($i=0; $i<$len; $i++) {
-                    $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';
-                }
-            }
-            
-            return $frame;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
-        {
-            $barcode_array = array();
-            
-            if (!is_array($mode))
-                $mode = explode(',', $mode);
-                
-            $eccLevel = 'L';
-                
-            if (count($mode) > 1) {
-                $eccLevel = $mode[1];
-            }
-                
-            $qrTab = QRcode::text($code, false, $eccLevel);
-            $size = count($qrTab);
-                
-            $barcode_array['num_rows'] = $size;
-            $barcode_array['num_cols'] = $size;
-            $barcode_array['bcode'] = array();
-                
-            foreach ($qrTab as $line) {
-                $arrAdd = array();
-                foreach(str_split($line) as $char)
-                    $arrAdd[] = ($char=='1')?1:0;
-                $barcode_array['bcode'][] = $arrAdd;
-            }
-                    
-            return $barcode_array;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function clearCache()
-        {
-            self::$frames = array();
-        }
-        
-        //----------------------------------------------------------------------
-        public static function buildCache()
-        {
-			QRtools::markTime('before_build_cache');
-			
-			$mask = new QRmask();
-            for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) {
-                $frame = QRspec::newFrame($a);
-                if (QR_IMAGE) {
-                    $fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
-                    QRimage::png(self::binarize($frame), $fileName, 1, 0);
-                }
-				
-				$width = count($frame);
-				$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
-				for ($maskNo=0; $maskNo<8; $maskNo++)
-					$mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
-            }
-			
-			QRtools::markTime('after_build_cache');
-        }
-
-        //----------------------------------------------------------------------
-        public static function log($outfile, $err)
-        {
-            if (QR_LOG_DIR !== false) {
-                if ($err != '') {
-                    if ($outfile !== false) {
-                        file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
-                    } else {
-                        file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
-                    }
-                }    
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public static function dumpMask($frame) 
-        {
-            $width = count($frame);
-            for($y=0;$y<$width;$y++) {
-                for($x=0;$x<$width;$x++) {
-                    echo ord($frame[$y][$x]).',';
-                }
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public static function markTime($markerId)
-        {
-            list($usec, $sec) = explode(" ", microtime());
-            $time = ((float)$usec + (float)$sec);
-            
-            if (!isset($GLOBALS['qr_time_bench']))
-                $GLOBALS['qr_time_bench'] = array();
-            
-            $GLOBALS['qr_time_bench'][$markerId] = $time;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function timeBenchmark()
-        {
-            self::markTime('finish');
-        
-            $lastTime = 0;
-            $startTime = 0;
-            $p = 0;
-
-            echo '<table cellpadding="3" cellspacing="1">
-                    <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>
-                    <tbody>';
-
-            foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
-                if ($p > 0) {
-                    echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime-$lastTime, 6).'s</td></tr>';
-                } else {
-                    $startTime = $thisTime;
-                }
-                
-                $p++;
-                $lastTime = $thisTime;
-            }
-            
-            echo '</tbody><tfoot>
-                <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime-$startTime, 6).'s</td></tr>
-            </tfoot>
-            </table>';
-        }
-        
-    }
-    
-    //##########################################################################
-    
-    QRtools::markTime('start');
-    
-
-
-
-//---- qrspec.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * QR Code specifications
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- *  or
- * "Automatic identification and data capture techniques -- 
- *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    define('QRSPEC_VERSION_MAX', 40);
-    define('QRSPEC_WIDTH_MAX',   177);
-
-    define('QRCAP_WIDTH',        0);
-    define('QRCAP_WORDS',        1);
-    define('QRCAP_REMINDER',     2);
-    define('QRCAP_EC',           3);
-
-    class QRspec {
-    
-        public static $capacity = array(
-            array(  0,    0, 0, array(   0,    0,    0,    0)),
-            array( 21,   26, 0, array(   7,   10,   13,   17)), // 1
-            array( 25,   44, 7, array(  10,   16,   22,   28)),
-            array( 29,   70, 7, array(  15,   26,   36,   44)),
-            array( 33,  100, 7, array(  20,   36,   52,   64)),
-            array( 37,  134, 7, array(  26,   48,   72,   88)), // 5
-            array( 41,  172, 7, array(  36,   64,   96,  112)),
-            array( 45,  196, 0, array(  40,   72,  108,  130)),
-            array( 49,  242, 0, array(  48,   88,  132,  156)),
-            array( 53,  292, 0, array(  60,  110,  160,  192)),
-            array( 57,  346, 0, array(  72,  130,  192,  224)), //10
-            array( 61,  404, 0, array(  80,  150,  224,  264)),
-            array( 65,  466, 0, array(  96,  176,  260,  308)),
-            array( 69,  532, 0, array( 104,  198,  288,  352)),
-            array( 73,  581, 3, array( 120,  216,  320,  384)),
-            array( 77,  655, 3, array( 132,  240,  360,  432)), //15
-            array( 81,  733, 3, array( 144,  280,  408,  480)),
-            array( 85,  815, 3, array( 168,  308,  448,  532)),
-            array( 89,  901, 3, array( 180,  338,  504,  588)),
-            array( 93,  991, 3, array( 196,  364,  546,  650)),
-            array( 97, 1085, 3, array( 224,  416,  600,  700)), //20
-            array(101, 1156, 4, array( 224,  442,  644,  750)),
-            array(105, 1258, 4, array( 252,  476,  690,  816)),
-            array(109, 1364, 4, array( 270,  504,  750,  900)),
-            array(113, 1474, 4, array( 300,  560,  810,  960)),
-            array(117, 1588, 4, array( 312,  588,  870, 1050)), //25
-            array(121, 1706, 4, array( 336,  644,  952, 1110)),
-            array(125, 1828, 4, array( 360,  700, 1020, 1200)),
-            array(129, 1921, 3, array( 390,  728, 1050, 1260)),
-            array(133, 2051, 3, array( 420,  784, 1140, 1350)),
-            array(137, 2185, 3, array( 450,  812, 1200, 1440)), //30
-            array(141, 2323, 3, array( 480,  868, 1290, 1530)),
-            array(145, 2465, 3, array( 510,  924, 1350, 1620)),
-            array(149, 2611, 3, array( 540,  980, 1440, 1710)),
-            array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
-            array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
-            array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
-            array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
-            array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
-            array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
-            array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
-        );
-        
-        //----------------------------------------------------------------------
-        public static function getDataLength($version, $level)
-        {
-            return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getECCLength($version, $level)
-        {
-            return self::$capacity[$version][QRCAP_EC][$level];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getWidth($version)
-        {
-            return self::$capacity[$version][QRCAP_WIDTH];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getRemainder($version)
-        {
-            return self::$capacity[$version][QRCAP_REMINDER];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getMinimumVersion($size, $level)
-        {
-
-            for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {
-                $words  = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
-                if($words >= $size) 
-                    return $i;
-            }
-
-            return -1;
-        }
-    
-        //######################################################################
-        
-        public static $lengthTableBits = array(
-            array(10, 12, 14),
-            array( 9, 11, 13),
-            array( 8, 16, 16),
-            array( 8, 10, 12)
-        );
-        
-        //----------------------------------------------------------------------
-        public static function lengthIndicator($mode, $version)
-        {
-            if ($mode == QR_MODE_STRUCTURE)
-                return 0;
-                
-            if ($version <= 9) {
-                $l = 0;
-            } else if ($version <= 26) {
-                $l = 1;
-            } else {
-                $l = 2;
-            }
-
-            return self::$lengthTableBits[$mode][$l];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function maximumWords($mode, $version)
-        {
-            if($mode == QR_MODE_STRUCTURE) 
-                return 3;
-                
-            if($version <= 9) {
-                $l = 0;
-            } else if($version <= 26) {
-                $l = 1;
-            } else {
-                $l = 2;
-            }
-
-            $bits = self::$lengthTableBits[$mode][$l];
-            $words = (1 << $bits) - 1;
-            
-            if($mode == QR_MODE_KANJI) {
-                $words *= 2; // the number of bytes is required
-            }
-
-            return $words;
-        }
-
-        // Error correction code -----------------------------------------------
-        // Table of the error correction code (Reed-Solomon block)
-        // See Table 12-16 (pp.30-36), JIS X0510:2004.
-
-        public static $eccTable = array(
-            array(array( 0,  0), array( 0,  0), array( 0,  0), array( 0,  0)),
-            array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)), // 1
-            array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)),
-            array(array( 1,  0), array( 1,  0), array( 2,  0), array( 2,  0)),
-            array(array( 1,  0), array( 2,  0), array( 2,  0), array( 4,  0)),
-            array(array( 1,  0), array( 2,  0), array( 2,  2), array( 2,  2)), // 5
-            array(array( 2,  0), array( 4,  0), array( 4,  0), array( 4,  0)),
-            array(array( 2,  0), array( 4,  0), array( 2,  4), array( 4,  1)),
-            array(array( 2,  0), array( 2,  2), array( 4,  2), array( 4,  2)),
-            array(array( 2,  0), array( 3,  2), array( 4,  4), array( 4,  4)),
-            array(array( 2,  2), array( 4,  1), array( 6,  2), array( 6,  2)), //10
-            array(array( 4,  0), array( 1,  4), array( 4,  4), array( 3,  8)),
-            array(array( 2,  2), array( 6,  2), array( 4,  6), array( 7,  4)),
-            array(array( 4,  0), array( 8,  1), array( 8,  4), array(12,  4)),
-            array(array( 3,  1), array( 4,  5), array(11,  5), array(11,  5)),
-            array(array( 5,  1), array( 5,  5), array( 5,  7), array(11,  7)), //15
-            array(array( 5,  1), array( 7,  3), array(15,  2), array( 3, 13)),
-            array(array( 1,  5), array(10,  1), array( 1, 15), array( 2, 17)),
-            array(array( 5,  1), array( 9,  4), array(17,  1), array( 2, 19)),
-            array(array( 3,  4), array( 3, 11), array(17,  4), array( 9, 16)),
-            array(array( 3,  5), array( 3, 13), array(15,  5), array(15, 10)), //20
-            array(array( 4,  4), array(17,  0), array(17,  6), array(19,  6)),
-            array(array( 2,  7), array(17,  0), array( 7, 16), array(34,  0)),
-            array(array( 4,  5), array( 4, 14), array(11, 14), array(16, 14)),
-            array(array( 6,  4), array( 6, 14), array(11, 16), array(30,  2)),
-            array(array( 8,  4), array( 8, 13), array( 7, 22), array(22, 13)), //25
-            array(array(10,  2), array(19,  4), array(28,  6), array(33,  4)),
-            array(array( 8,  4), array(22,  3), array( 8, 26), array(12, 28)),
-            array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
-            array(array( 7,  7), array(21,  7), array( 1, 37), array(19, 26)),
-            array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
-            array(array(13,  3), array( 2, 29), array(42,  1), array(23, 28)),
-            array(array(17,  0), array(10, 23), array(10, 35), array(19, 35)),
-            array(array(17,  1), array(14, 21), array(29, 19), array(11, 46)),
-            array(array(13,  6), array(14, 23), array(44,  7), array(59,  1)),
-            array(array(12,  7), array(12, 26), array(39, 14), array(22, 41)), //35
-            array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
-            array(array(17,  4), array(29, 14), array(49, 10), array(24, 46)),
-            array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
-            array(array(20,  4), array(40,  7), array(43, 22), array(10, 67)),
-            array(array(19,  6), array(18, 31), array(34, 34), array(20, 61)),//40
-        );                                                                       
-
-        //----------------------------------------------------------------------
-        // CACHEABLE!!!
-        
-        public static function getEccSpec($version, $level, array &$spec)
-        {
-            if (count($spec) < 5) {
-                $spec = array(0,0,0,0,0);
-            }
-
-            $b1   = self::$eccTable[$version][$level][0];
-            $b2   = self::$eccTable[$version][$level][1];
-            $data = self::getDataLength($version, $level);
-            $ecc  = self::getECCLength($version, $level);
-
-            if($b2 == 0) {
-                $spec[0] = $b1;
-                $spec[1] = (int)($data / $b1);
-                $spec[2] = (int)($ecc / $b1);
-                $spec[3] = 0; 
-                $spec[4] = 0;
-            } else {
-                $spec[0] = $b1;
-                $spec[1] = (int)($data / ($b1 + $b2));
-                $spec[2] = (int)($ecc  / ($b1 + $b2));
-                $spec[3] = $b2;
-                $spec[4] = $spec[1] + 1;
-            }
-        }
-
-        // Alignment pattern ---------------------------------------------------
-
-        // Positions of alignment patterns.
-        // This array includes only the second and the third position of the 
-        // alignment patterns. Rest of them can be calculated from the distance 
-        // between them.
-         
-        // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
-         
-        public static $alignmentPattern = array(      
-            array( 0,  0),
-            array( 0,  0), array(18,  0), array(22,  0), array(26,  0), array(30,  0), // 1- 5
-            array(34,  0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
-            array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
-            array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
-            array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
-            array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
-            array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
-            array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
-        );                                                                                  
-
-        
-        /** --------------------------------------------------------------------
-         * Put an alignment marker.
-         * @param frame
-         * @param width
-         * @param ox,oy center coordinate of the pattern
-         */
-        public static function putAlignmentMarker(array &$frame, $ox, $oy)
-        {
-            $finder = array(
-                "\xa1\xa1\xa1\xa1\xa1",
-                "\xa1\xa0\xa0\xa0\xa1",
-                "\xa1\xa0\xa1\xa0\xa1",
-                "\xa1\xa0\xa0\xa0\xa1",
-                "\xa1\xa1\xa1\xa1\xa1"
-            );                        
-            
-            $yStart = $oy-2;         
-            $xStart = $ox-2;
-            
-            for($y=0; $y<5; $y++) {
-                QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public static function putAlignmentPattern($version, &$frame, $width)
-        {
-            if($version < 2)
-                return;
-
-            $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
-            if($d < 0) {
-                $w = 2;
-            } else {
-                $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);
-            }
-
-            if($w * $w - 3 == 1) {
-                $x = self::$alignmentPattern[$version][0];
-                $y = self::$alignmentPattern[$version][0];
-                self::putAlignmentMarker($frame, $x, $y);
-                return;
-            }
-
-            $cx = self::$alignmentPattern[$version][0];
-            for($x=1; $x<$w - 1; $x++) {
-                self::putAlignmentMarker($frame, 6, $cx);
-                self::putAlignmentMarker($frame, $cx,  6);
-                $cx += $d;
-            }
-
-            $cy = self::$alignmentPattern[$version][0];
-            for($y=0; $y<$w-1; $y++) {
-                $cx = self::$alignmentPattern[$version][0];
-                for($x=0; $x<$w-1; $x++) {
-                    self::putAlignmentMarker($frame, $cx, $cy);
-                    $cx += $d;
-                }
-                $cy += $d;
-            }
-        }
-
-        // Version information pattern -----------------------------------------
-
-		// Version information pattern (BCH coded).
-        // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
-        
-		// size: [QRSPEC_VERSION_MAX - 6]
-		
-        public static $versionPattern = array(
-            0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
-            0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
-            0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
-            0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
-            0x27541, 0x28c69
-        );
-
-        //----------------------------------------------------------------------
-        public static function getVersionPattern($version)
-        {
-            if($version < 7 || $version > QRSPEC_VERSION_MAX)
-                return 0;
-
-            return self::$versionPattern[$version -7];
-        }
-
-        // Format information --------------------------------------------------
-        // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
-        
-        public static $formatInfo = array(
-            array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
-            array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
-            array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
-            array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
-        );
-
-        public static function getFormatInfo($mask, $level)
-        {
-            if($mask < 0 || $mask > 7)
-                return 0;
-                
-            if($level < 0 || $level > 3)
-                return 0;                
-
-            return self::$formatInfo[$level][$mask];
-        }
-
-        // Frame ---------------------------------------------------------------
-        // Cache of initial frames.
-         
-        public static $frames = array();
-
-        /** --------------------------------------------------------------------
-         * Put a finder pattern.
-         * @param frame
-         * @param width
-         * @param ox,oy upper-left coordinate of the pattern
-         */
-        public static function putFinderPattern(&$frame, $ox, $oy)
-        {
-            $finder = array(
-                "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
-                "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
-                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
-                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
-                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
-                "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
-                "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
-            );                            
-            
-            for($y=0; $y<7; $y++) {
-                QRstr::set($frame, $ox, $oy+$y, $finder[$y]);
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public static function createFrame($version)
-        {
-            $width = self::$capacity[$version][QRCAP_WIDTH];
-            $frameLine = str_repeat ("\0", $width);
-            $frame = array_fill(0, $width, $frameLine);
-
-            // Finder pattern
-            self::putFinderPattern($frame, 0, 0);
-            self::putFinderPattern($frame, $width - 7, 0);
-            self::putFinderPattern($frame, 0, $width - 7);
-            
-            // Separator
-            $yOffset = $width - 7;
-            
-            for($y=0; $y<7; $y++) {
-                $frame[$y][7] = "\xc0";
-                $frame[$y][$width - 8] = "\xc0";
-                $frame[$yOffset][7] = "\xc0";
-                $yOffset++;
-            }
-            
-            $setPattern = str_repeat("\xc0", 8);
-            
-            QRstr::set($frame, 0, 7, $setPattern);
-            QRstr::set($frame, $width-8, 7, $setPattern);
-            QRstr::set($frame, 0, $width - 8, $setPattern);
-        
-            // Format info
-            $setPattern = str_repeat("\x84", 9);
-            QRstr::set($frame, 0, 8, $setPattern);
-            QRstr::set($frame, $width - 8, 8, $setPattern, 8);
-            
-            $yOffset = $width - 8;
-
-            for($y=0; $y<8; $y++,$yOffset++) {
-                $frame[$y][8] = "\x84";
-                $frame[$yOffset][8] = "\x84";
-            }
-
-            // Timing pattern  
-            
-            for($i=1; $i<$width-15; $i++) {
-                $frame[6][7+$i] = chr(0x90 | ($i & 1));
-                $frame[7+$i][6] = chr(0x90 | ($i & 1));
-            }
-            
-            // Alignment pattern  
-            self::putAlignmentPattern($version, $frame, $width);
-            
-            // Version information 
-            if($version >= 7) {
-                $vinf = self::getVersionPattern($version);
-
-                $v = $vinf;
-                
-                for($x=0; $x<6; $x++) {
-                    for($y=0; $y<3; $y++) {
-                        $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));
-                        $v = $v >> 1;
-                    }
-                }
-
-                $v = $vinf;
-                for($y=0; $y<6; $y++) {
-                    for($x=0; $x<3; $x++) {
-                        $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));
-                        $v = $v >> 1;
-                    }
-                }
-            }
-    
-            // and a little bit...  
-            $frame[$width - 8][8] = "\x81";
-            
-            return $frame;
-        }
-
-        //----------------------------------------------------------------------
-        public static function debug($frame, $binary_mode = false)
-        {
-            if ($binary_mode) {
-            
-                    foreach ($frame as &$frameLine) {
-                        $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine));
-                        $frameLine = join('&#9608;&#9608;', explode('1', $frameLine));
-                    }
-                    
-                    ?>
-                <style>
-                    .m { background-color: white; }
-                </style>
-                <?php
-                    echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
-                    echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame);
-                    echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';
-            
-            } else {
-            
-                foreach ($frame as &$frameLine) {
-                    $frameLine = join('<span class="m">&nbsp;</span>',  explode("\xc0", $frameLine));
-                    $frameLine = join('<span class="m">&#9618;</span>', explode("\xc1", $frameLine));
-                    $frameLine = join('<span class="p">&nbsp;</span>',  explode("\xa0", $frameLine));
-                    $frameLine = join('<span class="p">&#9618;</span>', explode("\xa1", $frameLine));
-                    $frameLine = join('<span class="s">&#9671;</span>', explode("\x84", $frameLine)); //format 0
-                    $frameLine = join('<span class="s">&#9670;</span>', explode("\x85", $frameLine)); //format 1
-                    $frameLine = join('<span class="x">&#9762;</span>', explode("\x81", $frameLine)); //special bit
-                    $frameLine = join('<span class="c">&nbsp;</span>',  explode("\x90", $frameLine)); //clock 0
-                    $frameLine = join('<span class="c">&#9719;</span>', explode("\x91", $frameLine)); //clock 1
-                    $frameLine = join('<span class="f">&nbsp;</span>',  explode("\x88", $frameLine)); //version
-                    $frameLine = join('<span class="f">&#9618;</span>', explode("\x89", $frameLine)); //version
-                    $frameLine = join('&#9830;', explode("\x01", $frameLine));
-                    $frameLine = join('&#8901;', explode("\0", $frameLine));
-                }
-                
-                ?>
-                <style>
-                    .p { background-color: yellow; }
-                    .m { background-color: #00FF00; }
-                    .s { background-color: #FF0000; }
-                    .c { background-color: aqua; }
-                    .x { background-color: pink; }
-                    .f { background-color: gold; }
-                </style>
-                <?php
-                echo "<pre><tt>";
-                echo join("<br/ >", $frame);
-                echo "</tt></pre>";
-            
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public static function serial($frame)
-        {
-            return gzcompress(join("\n", $frame), 9);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function unserial($code)
-        {
-            return explode("\n", gzuncompress($code));
-        }
-        
-        //----------------------------------------------------------------------
-        public static function newFrame($version)
-        {
-            if($version < 1 || $version > QRSPEC_VERSION_MAX) 
-                return null;
-
-            if(!isset(self::$frames[$version])) {
-                
-                $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
-                
-                if (QR_CACHEABLE) {
-                    if (file_exists($fileName)) {
-                        self::$frames[$version] = self::unserial(file_get_contents($fileName));
-                    } else {
-                        self::$frames[$version] = self::createFrame($version);
-                        file_put_contents($fileName, self::serial(self::$frames[$version]));
-                    }
-                } else {
-                    self::$frames[$version] = self::createFrame($version);
-                }
-            }
-            
-            if(is_null(self::$frames[$version]))
-                return null;
-
-            return self::$frames[$version];
-        }
-
-        //----------------------------------------------------------------------
-        public static function rsBlockNum($spec)     { return $spec[0] + $spec[3]; }
-        public static function rsBlockNum1($spec)    { return $spec[0]; }
-        public static function rsDataCodes1($spec)   { return $spec[1]; }
-        public static function rsEccCodes1($spec)    { return $spec[2]; }
-        public static function rsBlockNum2($spec)    { return $spec[3]; }
-        public static function rsDataCodes2($spec)   { return $spec[4]; }
-        public static function rsEccCodes2($spec)    { return $spec[2]; }
-        public static function rsDataLength($spec)   { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);    }
-        public static function rsEccLength($spec)    { return ($spec[0] + $spec[3]) * $spec[2]; }
-        
-    }
-
-
-
-//---- qrimage.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Image output of code using GD2
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    define('QR_IMAGE', true);
-
-    class QRimage {
-    
-        //----------------------------------------------------------------------
-        public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) 
-        {
-            $image = self::image($frame, $pixelPerPoint, $outerFrame);
-            
-            if ($filename === false) {
-                Header("Content-type: image/png");
-                ImagePng($image);
-            } else {
-                if($saveandprint===TRUE){
-                    ImagePng($image, $filename);
-                    header("Content-type: image/png");
-                    ImagePng($image);
-                }else{
-                    ImagePng($image, $filename);
-                }
-            }
-            
-            ImageDestroy($image);
-        }
-    
-        //----------------------------------------------------------------------
-        public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) 
-        {
-            $image = self::image($frame, $pixelPerPoint, $outerFrame);
-            
-            if ($filename === false) {
-                Header("Content-type: image/jpeg");
-                ImageJpeg($image, null, $q);
-            } else {
-                ImageJpeg($image, $filename, $q);            
-            }
-            
-            ImageDestroy($image);
-        }
-    
-        //----------------------------------------------------------------------
-        private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) 
-        {
-            $h = count($frame);
-            $w = strlen($frame[0]);
-            
-            $imgW = $w + 2*$outerFrame;
-            $imgH = $h + 2*$outerFrame;
-            
-            $base_image =ImageCreate($imgW, $imgH);
-            
-            $col[0] = ImageColorAllocate($base_image,255,255,255);
-            $col[1] = ImageColorAllocate($base_image,0,0,0);
-
-            imagefill($base_image, 0, 0, $col[0]);
-
-            for($y=0; $y<$h; $y++) {
-                for($x=0; $x<$w; $x++) {
-                    if ($frame[$y][$x] == '1') {
-                        ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); 
-                    }
-                }
-            }
-            
-            $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
-            ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
-            ImageDestroy($base_image);
-            
-            return $target_image;
-        }
-    }
-
-
-
-//---- qrinput.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Input encoding class
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    define('STRUCTURE_HEADER_BITS',  20);
-    define('MAX_STRUCTURED_SYMBOLS', 16);
-
-    class QRinputItem {
-    
-        public $mode;
-        public $size;
-        public $data;
-        public $bstream;
-
-        public function __construct($mode, $size, $data, $bstream = null) 
-        {
-            $setData = array_slice($data, 0, $size);
-            
-            if (count($setData) < $size) {
-                $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
-            }
-        
-            if(!QRinput::check($mode, $size, $setData)) {
-                throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));
-                return null;
-            }
-            
-            $this->mode = $mode;
-            $this->size = $size;
-            $this->data = $setData;
-            $this->bstream = $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeModeNum($version)
-        {
-            try {
-            
-                $words = (int)($this->size / 3);
-                $bs = new QRbitstream();
-                
-                $val = 0x1;
-                $bs->appendNum(4, $val);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
-
-                for($i=0; $i<$words; $i++) {
-                    $val  = (ord($this->data[$i*3  ]) - ord('0')) * 100;
-                    $val += (ord($this->data[$i*3+1]) - ord('0')) * 10;
-                    $val += (ord($this->data[$i*3+2]) - ord('0'));
-                    $bs->appendNum(10, $val);
-                }
-
-                if($this->size - $words * 3 == 1) {
-                    $val = ord($this->data[$words*3]) - ord('0');
-                    $bs->appendNum(4, $val);
-                } else if($this->size - $words * 3 == 2) {
-                    $val  = (ord($this->data[$words*3  ]) - ord('0')) * 10;
-                    $val += (ord($this->data[$words*3+1]) - ord('0'));
-                    $bs->appendNum(7, $val);
-                }
-
-                $this->bstream = $bs;
-                return 0;
-                
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeModeAn($version)
-        {
-            try {
-                $words = (int)($this->size / 2);
-                $bs = new QRbitstream();
-                
-                $bs->appendNum(4, 0x02);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
-
-                for($i=0; $i<$words; $i++) {
-                    $val  = (int)QRinput::lookAnTable(ord($this->data[$i*2  ])) * 45;
-                    $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));
-
-                    $bs->appendNum(11, $val);
-                }
-
-                if($this->size & 1) {
-                    $val = QRinput::lookAnTable(ord($this->data[$words * 2]));
-                    $bs->appendNum(6, $val);
-                }
-        
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeMode8($version)
-        {
-            try {
-                $bs = new QRbitstream();
-
-                $bs->appendNum(4, 0x4);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
-
-                for($i=0; $i<$this->size; $i++) {
-                    $bs->appendNum(8, ord($this->data[$i]));
-                }
-
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeModeKanji($version)
-        {
-            try {
-
-                $bs = new QRbitrtream();
-                
-                $bs->appendNum(4, 0x8);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
-
-                for($i=0; $i<$this->size; $i+=2) {
-                    $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);
-                    if($val <= 0x9ffc) {
-                        $val -= 0x8140;
-                    } else {
-                        $val -= 0xc140;
-                    }
-                    
-                    $h = ($val >> 8) * 0xc0;
-                    $val = ($val & 0xff) + $h;
-
-                    $bs->appendNum(13, $val);
-                }
-
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public function encodeModeStructure()
-        {
-            try {
-                $bs =  new QRbitstream();
-                
-                $bs->appendNum(4, 0x03);
-                $bs->appendNum(4, ord($this->data[1]) - 1);
-                $bs->appendNum(4, ord($this->data[0]) - 1);
-                $bs->appendNum(8, ord($this->data[2]));
-
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function estimateBitStreamSizeOfEntry($version)
-        {
-            $bits = 0;
-
-            if($version == 0) 
-                $version = 1;
-
-            switch($this->mode) {
-                case QR_MODE_NUM:        $bits = QRinput::estimateBitsModeNum($this->size);    break;
-                case QR_MODE_AN:        $bits = QRinput::estimateBitsModeAn($this->size);    break;
-                case QR_MODE_8:            $bits = QRinput::estimateBitsMode8($this->size);    break;
-                case QR_MODE_KANJI:        $bits = QRinput::estimateBitsModeKanji($this->size);break;
-                case QR_MODE_STRUCTURE:    return STRUCTURE_HEADER_BITS;            
-                default:
-                    return 0;
-            }
-
-            $l = QRspec::lengthIndicator($this->mode, $version);
-            $m = 1 << $l;
-            $num = (int)(($this->size + $m - 1) / $m);
-
-            $bits += $num * (4 + $l);
-
-            return $bits;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeBitStream($version)
-        {
-            try {
-            
-                unset($this->bstream);
-                $words = QRspec::maximumWords($this->mode, $version);
-                
-                if($this->size > $words) {
-                
-                    $st1 = new QRinputItem($this->mode, $words, $this->data);
-                    $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
-
-                    $st1->encodeBitStream($version);
-                    $st2->encodeBitStream($version);
-                    
-                    $this->bstream = new QRbitstream();
-                    $this->bstream->append($st1->bstream);
-                    $this->bstream->append($st2->bstream);
-                    
-                    unset($st1);
-                    unset($st2);
-                    
-                } else {
-                    
-                    $ret = 0;
-                    
-                    switch($this->mode) {
-                        case QR_MODE_NUM:        $ret = $this->encodeModeNum($version);    break;
-                        case QR_MODE_AN:        $ret = $this->encodeModeAn($version);    break;
-                        case QR_MODE_8:            $ret = $this->encodeMode8($version);    break;
-                        case QR_MODE_KANJI:        $ret = $this->encodeModeKanji($version);break;
-                        case QR_MODE_STRUCTURE:    $ret = $this->encodeModeStructure();    break;
-                        
-                        default:
-                            break;
-                    }
-                    
-                    if($ret < 0)
-                        return -1;
-                }
-
-                return $this->bstream->size();
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-    };
-    
-    //##########################################################################
-
-    class QRinput {
-
-        public $items;
-        
-        private $version;
-        private $level;
-        
-        //----------------------------------------------------------------------
-        public function __construct($version = 0, $level = QR_ECLEVEL_L)
-        {
-            if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
-                throw new Exception('Invalid version no');
-                return NULL;
-            }
-            
-            $this->version = $version;
-            $this->level = $level;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getVersion()
-        {
-            return $this->version;
-        }
-        
-        //----------------------------------------------------------------------
-        public function setVersion($version)
-        {
-            if($version < 0 || $version > QRSPEC_VERSION_MAX) {
-                throw new Exception('Invalid version no');
-                return -1;
-            }
-
-            $this->version = $version;
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getErrorCorrectionLevel()
-        {
-            return $this->level;
-        }
-
-        //----------------------------------------------------------------------
-        public function setErrorCorrectionLevel($level)
-        {
-            if($level > QR_ECLEVEL_H) {
-                throw new Exception('Invalid ECLEVEL');
-                return -1;
-            }
-
-            $this->level = $level;
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function appendEntry(QRinputItem $entry)
-        {
-            $this->items[] = $entry;
-        }
-        
-        //----------------------------------------------------------------------
-        public function append($mode, $size, $data)
-        {
-            try {
-                $entry = new QRinputItem($mode, $size, $data);
-                $this->items[] = $entry;
-                return 0;
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        
-        public function insertStructuredAppendHeader($size, $index, $parity)
-        {
-            if( $size > MAX_STRUCTURED_SYMBOLS ) {
-                throw new Exception('insertStructuredAppendHeader wrong size');
-            }
-            
-            if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) {
-                throw new Exception('insertStructuredAppendHeader wrong index');
-            }
-
-            $buf = array($size, $index, $parity);
-            
-            try {
-                $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
-                array_unshift($this->items, $entry);
-                return 0;
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public function calcParity()
-        {
-            $parity = 0;
-            
-            foreach($this->items as $item) {
-                if($item->mode != QR_MODE_STRUCTURE) {
-                    for($i=$item->size-1; $i>=0; $i--) {
-                        $parity ^= $item->data[$i];
-                    }
-                }
-            }
-
-            return $parity;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function checkModeNum($size, $data)
-        {
-            for($i=0; $i<$size; $i++) {
-                if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        //----------------------------------------------------------------------
-        public static function estimateBitsModeNum($size)
-        {
-            $w = (int)$size / 3;
-            $bits = $w * 10;
-            
-            switch($size - $w * 3) {
-                case 1:
-                    $bits += 4;
-                    break;
-                case 2:
-                    $bits += 7;
-                    break;
-                default:
-                    break;
-            }
-
-            return $bits;
-        }
-        
-        //----------------------------------------------------------------------
-        public static $anTable = array(
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
-             0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1,
-            -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
-            25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-        );
-        
-        //----------------------------------------------------------------------
-        public static function lookAnTable($c)
-        {
-            return (($c > 127)?-1:self::$anTable[$c]);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function checkModeAn($size, $data)
-        {
-            for($i=0; $i<$size; $i++) {
-                if (self::lookAnTable(ord($data[$i])) == -1) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function estimateBitsModeAn($size)
-        {
-            $w = (int)($size / 2);
-            $bits = $w * 11;
-            
-            if($size & 1) {
-                $bits += 6;
-            }
-
-            return $bits;
-        }
-    
-        //----------------------------------------------------------------------
-        public static function estimateBitsMode8($size)
-        {
-            return $size * 8;
-        }
-        
-        //----------------------------------------------------------------------
-        public function estimateBitsModeKanji($size)
-        {
-            return (int)(($size / 2) * 13);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function checkModeKanji($size, $data)
-        {
-            if($size & 1)
-                return false;
-
-            for($i=0; $i<$size; $i+=2) {
-                $val = (ord($data[$i]) << 8) | ord($data[$i+1]);
-                if( $val < 0x8140 
-                || ($val > 0x9ffc && $val < 0xe040) 
-                || $val > 0xebbf) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        /***********************************************************************
-         * Validation
-         **********************************************************************/
-
-        public static function check($mode, $size, $data)
-        {
-            if($size <= 0) 
-                return false;
-
-            switch($mode) {
-                case QR_MODE_NUM:       return self::checkModeNum($size, $data);   break;
-                case QR_MODE_AN:        return self::checkModeAn($size, $data);    break;
-                case QR_MODE_KANJI:     return self::checkModeKanji($size, $data); break;
-                case QR_MODE_8:         return true; break;
-                case QR_MODE_STRUCTURE: return true; break;
-                
-                default:
-                    break;
-            }
-
-            return false;
-        }
-        
-        
-        //----------------------------------------------------------------------
-        public function estimateBitStreamSize($version)
-        {
-            $bits = 0;
-
-            foreach($this->items as $item) {
-                $bits += $item->estimateBitStreamSizeOfEntry($version);
-            }
-
-            return $bits;
-        }
-        
-        //----------------------------------------------------------------------
-        public function estimateVersion()
-        {
-            $version = 0;
-            $prev = 0;
-            do {
-                $prev = $version;
-                $bits = $this->estimateBitStreamSize($prev);
-                $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
-                if ($version < 0) {
-                    return -1;
-                }
-            } while ($version > $prev);
-
-            return $version;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function lengthOfCode($mode, $version, $bits)
-        {
-            $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
-            switch($mode) {
-                case QR_MODE_NUM:
-                    $chunks = (int)($payload / 10);
-                    $remain = $payload - $chunks * 10;
-                    $size = $chunks * 3;
-                    if($remain >= 7) {
-                        $size += 2;
-                    } else if($remain >= 4) {
-                        $size += 1;
-                    }
-                    break;
-                case QR_MODE_AN:
-                    $chunks = (int)($payload / 11);
-                    $remain = $payload - $chunks * 11;
-                    $size = $chunks * 2;
-                    if($remain >= 6) 
-                        $size++;
-                    break;
-                case QR_MODE_8:
-                    $size = (int)($payload / 8);
-                    break;
-                case QR_MODE_KANJI:
-                    $size = (int)(($payload / 13) * 2);
-                    break;
-                case QR_MODE_STRUCTURE:
-                    $size = (int)($payload / 8);
-                    break;
-                default:
-                    $size = 0;
-                    break;
-            }
-            
-            $maxsize = QRspec::maximumWords($mode, $version);
-            if($size < 0) $size = 0;
-            if($size > $maxsize) $size = $maxsize;
-
-            return $size;
-        }
-        
-        //----------------------------------------------------------------------
-        public function createBitStream()
-        {
-            $total = 0;
-
-            foreach($this->items as $item) {
-                $bits = $item->encodeBitStream($this->version);
-                
-                if($bits < 0) 
-                    return -1;
-                    
-                $total += $bits;
-            }
-
-            return $total;
-        }
-        
-        //----------------------------------------------------------------------
-        public function convertData()
-        {
-            $ver = $this->estimateVersion();
-            if($ver > $this->getVersion()) {
-                $this->setVersion($ver);
-            }
-
-            for(;;) {
-                $bits = $this->createBitStream();
-                
-                if($bits < 0) 
-                    return -1;
-                    
-                $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
-                if($ver < 0) {
-                    throw new Exception('WRONG VERSION');
-                    return -1;
-                } else if($ver > $this->getVersion()) {
-                    $this->setVersion($ver);
-                } else {
-                    break;
-                }
-            }
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function appendPaddingBit(&$bstream)
-        {
-            $bits = $bstream->size();
-            $maxwords = QRspec::getDataLength($this->version, $this->level);
-            $maxbits = $maxwords * 8;
-
-            if ($maxbits == $bits) {
-                return 0;
-            }
-
-            if ($maxbits - $bits < 5) {
-                return $bstream->appendNum($maxbits - $bits, 0);
-            }
-
-            $bits += 4;
-            $words = (int)(($bits + 7) / 8);
-
-            $padding = new QRbitstream();
-            $ret = $padding->appendNum($words * 8 - $bits + 4, 0);
-            
-            if($ret < 0) 
-                return $ret;
-
-            $padlen = $maxwords - $words;
-            
-            if($padlen > 0) {
-                
-                $padbuf = array();
-                for($i=0; $i<$padlen; $i++) {
-                    $padbuf[$i] = ($i&1)?0x11:0xec;
-                }
-                
-                $ret = $padding->appendBytes($padlen, $padbuf);
-                
-                if($ret < 0)
-                    return $ret;
-                
-            }
-
-            $ret = $bstream->append($padding);
-            
-            return $ret;
-        }
-
-        //----------------------------------------------------------------------
-        public function mergeBitStream()
-        {
-            if($this->convertData() < 0) {
-                return null;
-            }
-
-            $bstream = new QRbitstream();
-            
-            foreach($this->items as $item) {
-                $ret = $bstream->append($item->bstream);
-                if($ret < 0) {
-                    return null;
-                }
-            }
-
-            return $bstream;
-        }
-
-        //----------------------------------------------------------------------
-        public function getBitStream()
-        {
-
-            $bstream = $this->mergeBitStream();
-            
-            if($bstream == null) {
-                return null;
-            }
-            
-            $ret = $this->appendPaddingBit($bstream);
-            if($ret < 0) {
-                return null;
-            }
-
-            return $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getByteStream()
-        {
-            $bstream = $this->getBitStream();
-            if($bstream == null) {
-                return null;
-            }
-            
-            return $bstream->toByte();
-        }
-    }
-        
-        
-    
-
-
-
-//---- qrbitstream.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Bitstream class
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-     
-    class QRbitstream {
-    
-        public $data = array();
-        
-        //----------------------------------------------------------------------
-        public function size()
-        {
-            return count($this->data);
-        }
-        
-        //----------------------------------------------------------------------
-        public function allocate($setLength)
-        {
-            $this->data = array_fill(0, $setLength, 0);
-            return 0;
-        }
-    
-        //----------------------------------------------------------------------
-        public static function newFromNum($bits, $num)
-        {
-            $bstream = new QRbitstream();
-            $bstream->allocate($bits);
-            
-            $mask = 1 << ($bits - 1);
-            for($i=0; $i<$bits; $i++) {
-                if($num & $mask) {
-                    $bstream->data[$i] = 1;
-                } else {
-                    $bstream->data[$i] = 0;
-                }
-                $mask = $mask >> 1;
-            }
-
-            return $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function newFromBytes($size, $data)
-        {
-            $bstream = new QRbitstream();
-            $bstream->allocate($size * 8);
-            $p=0;
-
-            for($i=0; $i<$size; $i++) {
-                $mask = 0x80;
-                for($j=0; $j<8; $j++) {
-                    if($data[$i] & $mask) {
-                        $bstream->data[$p] = 1;
-                    } else {
-                        $bstream->data[$p] = 0;
-                    }
-                    $p++;
-                    $mask = $mask >> 1;
-                }
-            }
-
-            return $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public function append(QRbitstream $arg)
-        {
-            if (is_null($arg)) {
-                return -1;
-            }
-            
-            if($arg->size() == 0) {
-                return 0;
-            }
-            
-            if($this->size() == 0) {
-                $this->data = $arg->data;
-                return 0;
-            }
-            
-            $this->data = array_values(array_merge($this->data, $arg->data));
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function appendNum($bits, $num)
-        {
-            if ($bits == 0) 
-                return 0;
-
-            $b = QRbitstream::newFromNum($bits, $num);
-            
-            if(is_null($b))
-                return -1;
-
-            $ret = $this->append($b);
-            unset($b);
-
-            return $ret;
-        }
-
-        //----------------------------------------------------------------------
-        public function appendBytes($size, $data)
-        {
-            if ($size == 0) 
-                return 0;
-
-            $b = QRbitstream::newFromBytes($size, $data);
-            
-            if(is_null($b))
-                return -1;
-
-            $ret = $this->append($b);
-            unset($b);
-
-            return $ret;
-        }
-        
-        //----------------------------------------------------------------------
-        public function toByte()
-        {
-        
-            $size = $this->size();
-
-            if($size == 0) {
-                return array();
-            }
-            
-            $data = array_fill(0, (int)(($size + 7) / 8), 0);
-            $bytes = (int)($size / 8);
-
-            $p = 0;
-            
-            for($i=0; $i<$bytes; $i++) {
-                $v = 0;
-                for($j=0; $j<8; $j++) {
-                    $v = $v << 1;
-                    $v |= $this->data[$p];
-                    $p++;
-                }
-                $data[$i] = $v;
-            }
-            
-            if($size & 7) {
-                $v = 0;
-                for($j=0; $j<($size & 7); $j++) {
-                    $v = $v << 1;
-                    $v |= $this->data[$p];
-                    $p++;
-                }
-                $data[$bytes] = $v;
-            }
-
-            return $data;
-        }
-
-    }
-
-
-
-
-//---- qrsplit.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Input splitting classes
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- *  or
- * "Automatic identification and data capture techniques -- 
- *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-    class QRsplit {
-
-        public $dataStr = '';
-        public $input;
-        public $modeHint;
-
-        //----------------------------------------------------------------------
-        public function __construct($dataStr, $input, $modeHint) 
-        {
-            $this->dataStr  = $dataStr;
-            $this->input    = $input;
-            $this->modeHint = $modeHint;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function isdigitat($str, $pos)
-        {    
-            if ($pos >= strlen($str))
-                return false;
-            
-            return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));
-        }
-        
-        //----------------------------------------------------------------------
-        public static function isalnumat($str, $pos)
-        {
-            if ($pos >= strlen($str))
-                return false;
-                
-            return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
-        }
-
-        //----------------------------------------------------------------------
-        public function identifyMode($pos)
-        {
-            if ($pos >= strlen($this->dataStr)) 
-                return QR_MODE_NUL;
-                
-            $c = $this->dataStr[$pos];
-            
-            if(self::isdigitat($this->dataStr, $pos)) {
-                return QR_MODE_NUM;
-            } else if(self::isalnumat($this->dataStr, $pos)) {
-                return QR_MODE_AN;
-            } else if($this->modeHint == QR_MODE_KANJI) {
-            
-                if ($pos+1 < strlen($this->dataStr)) 
-                {
-                    $d = $this->dataStr[$pos+1];
-                    $word = (ord($c) << 8) | ord($d);
-                    if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
-                        return QR_MODE_KANJI;
-                    }
-                }
-            }
-
-            return QR_MODE_8;
-        } 
-        
-        //----------------------------------------------------------------------
-        public function eatNum()
-        {
-            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
-            $p = 0;
-            while(self::isdigitat($this->dataStr, $p)) {
-                $p++;
-            }
-            
-            $run = $p;
-            $mode = $this->identifyMode($p);
-            
-            if($mode == QR_MODE_8) {
-                $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
-                     + QRinput::estimateBitsMode8(1)         // + 4 + l8
-                     - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
-                if($dif > 0) {
-                    return $this->eat8();
-                }
-            }
-            if($mode == QR_MODE_AN) {
-                $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
-                     + QRinput::estimateBitsModeAn(1)        // + 4 + la
-                     - QRinput::estimateBitsModeAn($run + 1);// - 4 - la
-                if($dif > 0) {
-                    return $this->eatAn();
-                }
-            }
-            
-            $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-        
-        //----------------------------------------------------------------------
-        public function eatAn()
-        {
-            $la = QRspec::lengthIndicator(QR_MODE_AN,  $this->input->getVersion());
-            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
-            $p = 0;
-            
-            while(self::isalnumat($this->dataStr, $p)) {
-                if(self::isdigitat($this->dataStr, $p)) {
-                    $q = $p;
-                    while(self::isdigitat($this->dataStr, $q)) {
-                        $q++;
-                    }
-                    
-                    $dif = QRinput::estimateBitsModeAn($p) // + 4 + la
-                         + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
-                         - QRinput::estimateBitsModeAn($q); // - 4 - la
-                         
-                    if($dif < 0) {
-                        break;
-                    } else {
-                        $p = $q;
-                    }
-                } else {
-                    $p++;
-                }
-            }
-
-            $run = $p;
-
-            if(!self::isalnumat($this->dataStr, $p)) {
-                $dif = QRinput::estimateBitsModeAn($run) + 4 + $la
-                     + QRinput::estimateBitsMode8(1) // + 4 + l8
-                      - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
-                if($dif > 0) {
-                    return $this->eat8();
-                }
-            }
-
-            $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-        
-        //----------------------------------------------------------------------
-        public function eatKanji()
-        {
-            $p = 0;
-            
-            while($this->identifyMode($p) == QR_MODE_KANJI) {
-                $p += 2;
-            }
-            
-            $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-
-        //----------------------------------------------------------------------
-        public function eat8()
-        {
-            $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
-            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
-            $p = 1;
-            $dataStrLen = strlen($this->dataStr);
-            
-            while($p < $dataStrLen) {
-                
-                $mode = $this->identifyMode($p);
-                if($mode == QR_MODE_KANJI) {
-                    break;
-                }
-                if($mode == QR_MODE_NUM) {
-                    $q = $p;
-                    while(self::isdigitat($this->dataStr, $q)) {
-                        $q++;
-                    }
-                    $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
-                         + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
-                         - QRinput::estimateBitsMode8($q); // - 4 - l8
-                    if($dif < 0) {
-                        break;
-                    } else {
-                        $p = $q;
-                    }
-                } else if($mode == QR_MODE_AN) {
-                    $q = $p;
-                    while(self::isalnumat($this->dataStr, $q)) {
-                        $q++;
-                    }
-                    $dif = QRinput::estimateBitsMode8($p)  // + 4 + l8
-                         + QRinput::estimateBitsModeAn($q - $p) + 4 + $la
-                         - QRinput::estimateBitsMode8($q); // - 4 - l8
-                    if($dif < 0) {
-                        break;
-                    } else {
-                        $p = $q;
-                    }
-                } else {
-                    $p++;
-                }
-            }
-
-            $run = $p;
-            $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
-            
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-
-        //----------------------------------------------------------------------
-        public function splitString()
-        {
-            while (strlen($this->dataStr) > 0)
-            {
-                if($this->dataStr == '')
-                    return 0;
-
-                $mode = $this->identifyMode(0);
-                
-                switch ($mode) {
-                    case QR_MODE_NUM: $length = $this->eatNum(); break;
-                    case QR_MODE_AN:  $length = $this->eatAn(); break;
-                    case QR_MODE_KANJI:
-                        if ($hint == QR_MODE_KANJI)
-                                $length = $this->eatKanji();
-                        else    $length = $this->eat8();
-                        break;
-                    default: $length = $this->eat8(); break;
-                
-                }
-
-                if($length == 0) return 0;
-                if($length < 0)  return -1;
-                
-                $this->dataStr = substr($this->dataStr, $length);
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public function toUpper()
-        {
-            $stringLen = strlen($this->dataStr);
-            $p = 0;
-            
-            while ($p<$stringLen) {
-                $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);
-                if($mode == QR_MODE_KANJI) {
-                    $p += 2;
-                } else {
-                    if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {
-                        $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
-                    }
-                    $p++;
-                }
-            }
-
-            return $this->dataStr;
-        }
-
-        //----------------------------------------------------------------------
-        public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
-        {
-            if(is_null($string) || $string == '\0' || $string == '') {
-                throw new Exception('empty string!!!');
-            }
-
-            $split = new QRsplit($string, $input, $modeHint);
-            
-            if(!$casesensitive)
-                $split->toUpper();
-                
-            return $split->splitString();
-        }
-    }
-
-
-
-//---- qrrscode.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Reed-Solomon error correction support
- * 
- * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
- * (libfec is released under the GNU Lesser General Public License.)
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    class QRrsItem {
-    
-        public $mm;                  // Bits per symbol 
-        public $nn;                  // Symbols per block (= (1<<mm)-1) 
-        public $alpha_to = array();  // log lookup table 
-        public $index_of = array();  // Antilog lookup table 
-        public $genpoly = array();   // Generator polynomial 
-        public $nroots;              // Number of generator roots = number of parity symbols 
-        public $fcr;                 // First consecutive root, index form 
-        public $prim;                // Primitive element, index form 
-        public $iprim;               // prim-th root of 1, index form 
-        public $pad;                 // Padding bytes in shortened block 
-        public $gfpoly;
-    
-        //----------------------------------------------------------------------
-        public function modnn($x)
-        {
-            while ($x >= $this->nn) {
-                $x -= $this->nn;
-                $x = ($x >> $this->mm) + ($x & $this->nn);
-            }
-            
-            return $x;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
-        {
-            // Common code for intializing a Reed-Solomon control block (char or int symbols)
-            // Copyright 2004 Phil Karn, KA9Q
-            // May be used under the terms of the GNU Lesser General Public License (LGPL)
-
-            $rs = null;
-            
-            // Check parameter ranges
-            if($symsize < 0 || $symsize > 8)                     return $rs;
-            if($fcr < 0 || $fcr >= (1<<$symsize))                return $rs;
-            if($prim <= 0 || $prim >= (1<<$symsize))             return $rs;
-            if($nroots < 0 || $nroots >= (1<<$symsize))          return $rs; // Can't have more roots than symbol values!
-            if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
-
-            $rs = new QRrsItem();
-            $rs->mm = $symsize;
-            $rs->nn = (1<<$symsize)-1;
-            $rs->pad = $pad;
-
-            $rs->alpha_to = array_fill(0, $rs->nn+1, 0);
-            $rs->index_of = array_fill(0, $rs->nn+1, 0);
-          
-            // PHP style macro replacement ;)
-            $NN =& $rs->nn;
-            $A0 =& $NN;
-            
-            // Generate Galois field lookup tables
-            $rs->index_of[0] = $A0; // log(zero) = -inf
-            $rs->alpha_to[$A0] = 0; // alpha**-inf = 0
-            $sr = 1;
-          
-            for($i=0; $i<$rs->nn; $i++) {
-                $rs->index_of[$sr] = $i;
-                $rs->alpha_to[$i] = $sr;
-                $sr <<= 1;
-                if($sr & (1<<$symsize)) {
-                    $sr ^= $gfpoly;
-                }
-                $sr &= $rs->nn;
-            }
-            
-            if($sr != 1){
-                // field generator polynomial is not primitive!
-                $rs = NULL;
-                return $rs;
-            }
-
-            /* Form RS code generator polynomial from its roots */
-            $rs->genpoly = array_fill(0, $nroots+1, 0);
-        
-            $rs->fcr = $fcr;
-            $rs->prim = $prim;
-            $rs->nroots = $nroots;
-            $rs->gfpoly = $gfpoly;
-
-            /* Find prim-th root of 1, used in decoding */
-            for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)
-            ; // intentional empty-body loop!
-            
-            $rs->iprim = (int)($iprim / $prim);
-            $rs->genpoly[0] = 1;
-            
-            for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
-                $rs->genpoly[$i+1] = 1;
-
-                // Multiply rs->genpoly[] by  @**(root + x)
-                for ($j = $i; $j > 0; $j--) {
-                    if ($rs->genpoly[$j] != 0) {
-                        $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
-                    } else {
-                        $rs->genpoly[$j] = $rs->genpoly[$j-1];
-                    }
-                }
-                // rs->genpoly[0] can never be zero
-                $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
-            }
-            
-            // convert rs->genpoly[] to index form for quicker encoding
-            for ($i = 0; $i <= $nroots; $i++)
-                $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
-
-            return $rs;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encode_rs_char($data, &$parity)
-        {
-            $MM       =& $this->mm;
-            $NN       =& $this->nn;
-            $ALPHA_TO =& $this->alpha_to;
-            $INDEX_OF =& $this->index_of;
-            $GENPOLY  =& $this->genpoly;
-            $NROOTS   =& $this->nroots;
-            $FCR      =& $this->fcr;
-            $PRIM     =& $this->prim;
-            $IPRIM    =& $this->iprim;
-            $PAD      =& $this->pad;
-            $A0       =& $NN;
-
-            $parity = array_fill(0, $NROOTS, 0);
-
-            for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) {
-                
-                $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
-                if($feedback != $A0) {      
-                    // feedback term is non-zero
-            
-                    // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
-                    // always be for the polynomials constructed by init_rs()
-                    $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
-            
-                    for($j=1;$j<$NROOTS;$j++) {
-                        $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];
-                    }
-                }
-                
-                // Shift 
-                array_shift($parity);
-                if($feedback != $A0) {
-                    array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
-                } else {
-                    array_push($parity, 0);
-                }
-            }
-        }
-    }
-    
-    //##########################################################################
-    
-    class QRrs {
-    
-        public static $items = array();
-        
-        //----------------------------------------------------------------------
-        public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
-        {
-            foreach(self::$items as $rs) {
-                if($rs->pad != $pad)       continue;
-                if($rs->nroots != $nroots) continue;
-                if($rs->mm != $symsize)    continue;
-                if($rs->gfpoly != $gfpoly) continue;
-                if($rs->fcr != $fcr)       continue;
-                if($rs->prim != $prim)     continue;
-
-                return $rs;
-            }
-
-            $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
-            array_unshift(self::$items, $rs);
-
-            return $rs;
-        }
-    }
-
-
-
-//---- qrmask.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Masking
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-	define('N1', 3);
-	define('N2', 3);
-	define('N3', 40);
-	define('N4', 10);
-
-	class QRmask {
-	
-		public $runLength = array();
-		
-		//----------------------------------------------------------------------
-		public function __construct() 
-        {
-            $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
-        }
-        
-        //----------------------------------------------------------------------
-        public function writeFormatInformation($width, &$frame, $mask, $level)
-        {
-            $blacks = 0;
-            $format =  QRspec::getFormatInfo($mask, $level);
-
-            for($i=0; $i<8; $i++) {
-                if($format & 1) {
-                    $blacks += 2;
-                    $v = 0x85;
-                } else {
-                    $v = 0x84;
-                }
-                
-                $frame[8][$width - 1 - $i] = chr($v);
-                if($i < 6) {
-                    $frame[$i][8] = chr($v);
-                } else {
-                    $frame[$i + 1][8] = chr($v);
-                }
-                $format = $format >> 1;
-            }
-            
-            for($i=0; $i<7; $i++) {
-                if($format & 1) {
-                    $blacks += 2;
-                    $v = 0x85;
-                } else {
-                    $v = 0x84;
-                }
-                
-                $frame[$width - 7 + $i][8] = chr($v);
-                if($i == 0) {
-                    $frame[8][7] = chr($v);
-                } else {
-                    $frame[8][6 - $i] = chr($v);
-                }
-                
-                $format = $format >> 1;
-            }
-
-            return $blacks;
-        }
-        
-        //----------------------------------------------------------------------
-        public function mask0($x, $y) { return ($x+$y)&1;                       }
-        public function mask1($x, $y) { return ($y&1);                          }
-        public function mask2($x, $y) { return ($x%3);                          }
-        public function mask3($x, $y) { return ($x+$y)%3;                       }
-        public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; }
-        public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3;           }
-        public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1;       }
-        public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1;     }
-        
-        //----------------------------------------------------------------------
-        private function generateMaskNo($maskNo, $width, $frame)
-        {
-            $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
-            
-            for($y=0; $y<$width; $y++) {
-                for($x=0; $x<$width; $x++) {
-                    if(ord($frame[$y][$x]) & 0x80) {
-                        $bitMask[$y][$x] = 0;
-                    } else {
-                        $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
-                        $bitMask[$y][$x] = ($maskFunc == 0)?1:0;
-                    }
-                    
-                }
-            }
-            
-            return $bitMask;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function serial($bitFrame)
-        {
-            $codeArr = array();
-            
-            foreach ($bitFrame as $line)
-                $codeArr[] = join('', $line);
-                
-            return gzcompress(join("\n", $codeArr), 9);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function unserial($code)
-        {
-            $codeArr = array();
-            
-            $codeLines = explode("\n", gzuncompress($code));
-            foreach ($codeLines as $line)
-                $codeArr[] = str_split($line);
-            
-            return $codeArr;
-        }
-        
-        //----------------------------------------------------------------------
-        public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) 
-        {
-            $b = 0;
-            $bitMask = array();
-            
-            $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
-
-            if (QR_CACHEABLE) {
-                if (file_exists($fileName)) {
-                    $bitMask = self::unserial(file_get_contents($fileName));
-                } else {
-                    $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
-                    if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))
-                        mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
-                    file_put_contents($fileName, self::serial($bitMask));
-                }
-            } else {
-                $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
-            }
-
-            if ($maskGenOnly)
-                return;
-                
-            $d = $s;
-
-            for($y=0; $y<$width; $y++) {
-                for($x=0; $x<$width; $x++) {
-                    if($bitMask[$y][$x] == 1) {
-                        $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);
-                    }
-                    $b += (int)(ord($d[$y][$x]) & 1);
-                }
-            }
-
-            return $b;
-        }
-        
-        //----------------------------------------------------------------------
-        public function makeMask($width, $frame, $maskNo, $level)
-        {
-            $masked = array_fill(0, $width, str_repeat("\0", $width));
-            $this->makeMaskNo($maskNo, $width, $frame, $masked);
-            $this->writeFormatInformation($width, $masked, $maskNo, $level);
-       
-            return $masked;
-        }
-        
-        //----------------------------------------------------------------------
-        public function calcN1N3($length)
-        {
-            $demerit = 0;
-
-            for($i=0; $i<$length; $i++) {
-                
-                if($this->runLength[$i] >= 5) {
-                    $demerit += (N1 + ($this->runLength[$i] - 5));
-                }
-                if($i & 1) {
-                    if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) {
-                        $fact = (int)($this->runLength[$i] / 3);
-                        if(($this->runLength[$i-2] == $fact) &&
-                           ($this->runLength[$i-1] == $fact) &&
-                           ($this->runLength[$i+1] == $fact) &&
-                           ($this->runLength[$i+2] == $fact)) {
-                            if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) {
-                                $demerit += N3;
-                            } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) {
-                                $demerit += N3;
-                            }
-                        }
-                    }
-                }
-            }
-            return $demerit;
-        }
-        
-        //----------------------------------------------------------------------
-        public function evaluateSymbol($width, $frame)
-        {
-            $head = 0;
-            $demerit = 0;
-
-            for($y=0; $y<$width; $y++) {
-                $head = 0;
-                $this->runLength[0] = 1;
-                
-                $frameY = $frame[$y];
-                
-                if ($y>0)
-                    $frameYM = $frame[$y-1];
-                
-                for($x=0; $x<$width; $x++) {
-                    if(($x > 0) && ($y > 0)) {
-                        $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
-                        $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
-                        
-                        if(($b22 | ($w22 ^ 1))&1) {                                                                     
-                            $demerit += N2;
-                        }
-                    }
-                    if(($x == 0) && (ord($frameY[$x]) & 1)) {
-                        $this->runLength[0] = -1;
-                        $head = 1;
-                        $this->runLength[$head] = 1;
-                    } else if($x > 0) {
-                        if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
-                            $head++;
-                            $this->runLength[$head] = 1;
-                        } else {
-                            $this->runLength[$head]++;
-                        }
-                    }
-                }
-    
-                $demerit += $this->calcN1N3($head+1);
-            }
-
-            for($x=0; $x<$width; $x++) {
-                $head = 0;
-                $this->runLength[0] = 1;
-                
-                for($y=0; $y<$width; $y++) {
-                    if($y == 0 && (ord($frame[$y][$x]) & 1)) {
-                        $this->runLength[0] = -1;
-                        $head = 1;
-                        $this->runLength[$head] = 1;
-                    } else if($y > 0) {
-                        if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
-                            $head++;
-                            $this->runLength[$head] = 1;
-                        } else {
-                            $this->runLength[$head]++;
-                        }
-                    }
-                }
-            
-                $demerit += $this->calcN1N3($head+1);
-            }
-
-            return $demerit;
-        }
-        
-        
-        //----------------------------------------------------------------------
-        public function mask($width, $frame, $level)
-        {
-            $minDemerit = PHP_INT_MAX;
-            $bestMaskNum = 0;
-            $bestMask = array();
-            
-            $checked_masks = array(0,1,2,3,4,5,6,7);
-            
-            if (QR_FIND_FROM_RANDOM !== false) {
-            
-                $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
-                for ($i = 0; $i <  $howManuOut; $i++) {
-                    $remPos = rand (0, count($checked_masks)-1);
-                    unset($checked_masks[$remPos]);
-                    $checked_masks = array_values($checked_masks);
-                }
-            
-            }
-            
-            $bestMask = $frame;
-             
-            foreach($checked_masks as $i) {
-                $mask = array_fill(0, $width, str_repeat("\0", $width));
-
-                $demerit = 0;
-                $blacks = 0;
-                $blacks  = $this->makeMaskNo($i, $width, $frame, $mask);
-                $blacks += $this->writeFormatInformation($width, $mask, $i, $level);
-                $blacks  = (int)(100 * $blacks / ($width * $width));
-                $demerit = (int)((int)(abs($blacks - 50) / 5) * N4);
-                $demerit += $this->evaluateSymbol($width, $mask);
-                
-                if($demerit < $minDemerit) {
-                    $minDemerit = $demerit;
-                    $bestMask = $mask;
-                    $bestMaskNum = $i;
-                }
-            }
-            
-            return $bestMask;
-        }
-        
-        //----------------------------------------------------------------------
-    }
-
-
-
-
-//---- qrencode.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Main encoder classes.
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    class QRrsblock {
-        public $dataLength;
-        public $data = array();
-        public $eccLength;
-        public $ecc = array();
-        
-        public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
-        {
-            $rs->encode_rs_char($data, $ecc);
-        
-            $this->dataLength = $dl;
-            $this->data = $data;
-            $this->eccLength = $el;
-            $this->ecc = $ecc;
-        }
-    };
-    
-    //##########################################################################
-
-    class QRrawcode {
-        public $version;
-        public $datacode = array();
-        public $ecccode = array();
-        public $blocks;
-        public $rsblocks = array(); //of RSblock
-        public $count;
-        public $dataLength;
-        public $eccLength;
-        public $b1;
-        
-        //----------------------------------------------------------------------
-        public function __construct(QRinput $input)
-        {
-            $spec = array(0,0,0,0,0);
-            
-            $this->datacode = $input->getByteStream();
-            if(is_null($this->datacode)) {
-                throw new Exception('null imput string');
-            }
-
-            QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
-
-            $this->version = $input->getVersion();
-            $this->b1 = QRspec::rsBlockNum1($spec);
-            $this->dataLength = QRspec::rsDataLength($spec);
-            $this->eccLength = QRspec::rsEccLength($spec);
-            $this->ecccode = array_fill(0, $this->eccLength, 0);
-            $this->blocks = QRspec::rsBlockNum($spec);
-            
-            $ret = $this->init($spec);
-            if($ret < 0) {
-                throw new Exception('block alloc error');
-                return null;
-            }
-
-            $this->count = 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function init(array $spec)
-        {
-            $dl = QRspec::rsDataCodes1($spec);
-            $el = QRspec::rsEccCodes1($spec);
-            $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-            
-
-            $blockNo = 0;
-            $dataPos = 0;
-            $eccPos = 0;
-            for($i=0; $i<QRspec::rsBlockNum1($spec); $i++) {
-                $ecc = array_slice($this->ecccode,$eccPos);
-                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el,  $ecc, $rs);
-                $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-                
-                $dataPos += $dl;
-                $eccPos += $el;
-                $blockNo++;
-            }
-
-            if(QRspec::rsBlockNum2($spec) == 0)
-                return 0;
-
-            $dl = QRspec::rsDataCodes2($spec);
-            $el = QRspec::rsEccCodes2($spec);
-            $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-            
-            if($rs == NULL) return -1;
-            
-            for($i=0; $i<QRspec::rsBlockNum2($spec); $i++) {
-                $ecc = array_slice($this->ecccode,$eccPos);
-                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
-                $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-                
-                $dataPos += $dl;
-                $eccPos += $el;
-                $blockNo++;
-            }
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getCode()
-        {
-            $ret;
-
-            if($this->count < $this->dataLength) {
-                $row = $this->count % $this->blocks;
-                $col = $this->count / $this->blocks;
-                if($col >= $this->rsblocks[0]->dataLength) {
-                    $row += $this->b1;
-                }
-                $ret = $this->rsblocks[$row]->data[$col];
-            } else if($this->count < $this->dataLength + $this->eccLength) {
-                $row = ($this->count - $this->dataLength) % $this->blocks;
-                $col = ($this->count - $this->dataLength) / $this->blocks;
-                $ret = $this->rsblocks[$row]->ecc[$col];
-            } else {
-                return 0;
-            }
-            $this->count++;
-            
-            return $ret;
-        }
-    }
-
-    //##########################################################################
-    
-    class QRcode {
-    
-        public $version;
-        public $width;
-        public $data; 
-        
-        //----------------------------------------------------------------------
-        public function encodeMask(QRinput $input, $mask)
-        {
-            if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {
-                throw new Exception('wrong version');
-            }
-            if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
-                throw new Exception('wrong level');
-            }
-
-            $raw = new QRrawcode($input);
-            
-            QRtools::markTime('after_raw');
-            
-            $version = $raw->version;
-            $width = QRspec::getWidth($version);
-            $frame = QRspec::newFrame($version);
-            
-            $filler = new FrameFiller($width, $frame);
-            if(is_null($filler)) {
-                return NULL;
-            }
-
-            // inteleaved data and ecc codes
-            for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {
-                $code = $raw->getCode();
-                $bit = 0x80;
-                for($j=0; $j<8; $j++) {
-                    $addr = $filler->next();
-                    $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
-                    $bit = $bit >> 1;
-                }
-            }
-            
-            QRtools::markTime('after_filler');
-            
-            unset($raw);
-            
-            // remainder bits
-            $j = QRspec::getRemainder($version);
-            for($i=0; $i<$j; $i++) {
-                $addr = $filler->next();
-                $filler->setFrameAt($addr, 0x02);
-            }
-            
-            $frame = $filler->frame;
-            unset($filler);
-            
-            
-            // masking
-            $maskObj = new QRmask();
-            if($mask < 0) {
-            
-                if (QR_FIND_BEST_MASK) {
-                    $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
-                } else {
-                    $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
-                }
-            } else {
-                $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
-            }
-            
-            if($masked == NULL) {
-                return NULL;
-            }
-            
-            QRtools::markTime('after_mask');
-            
-            $this->version = $version;
-            $this->width = $width;
-            $this->data = $masked;
-            
-            return $this;
-        }
-    
-        //----------------------------------------------------------------------
-        public function encodeInput(QRinput $input)
-        {
-            return $this->encodeMask($input, -1);
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeString8bit($string, $version, $level)
-        {
-            if(string == NULL) {
-                throw new Exception('empty string!');
-                return NULL;
-            }
-
-            $input = new QRinput($version, $level);
-            if($input == NULL) return NULL;
-
-            $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));
-            if($ret < 0) {
-                unset($input);
-                return NULL;
-            }
-            return $this->encodeInput($input);
-        }
-
-        //----------------------------------------------------------------------
-        public function encodeString($string, $version, $level, $hint, $casesensitive)
-        {
-
-            if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
-                throw new Exception('bad hint');
-                return NULL;
-            }
-
-            $input = new QRinput($version, $level);
-            if($input == NULL) return NULL;
-
-            $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
-            if($ret < 0) {
-                return NULL;
-            }
-
-            return $this->encodeInput($input);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) 
-        {
-            $enc = QRencode::factory($level, $size, $margin);
-            return $enc->encodePNG($text, $outfile, $saveandprint=false);
-        }
-
-        //----------------------------------------------------------------------
-        public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
-        {
-            $enc = QRencode::factory($level, $size, $margin);
-            return $enc->encode($text, $outfile);
-        }
-
-        //----------------------------------------------------------------------
-        public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
-        {
-            $enc = QRencode::factory($level, $size, $margin);
-            return $enc->encodeRAW($text, $outfile);
-        }
-    }
-    
-    //##########################################################################
-    
-    class FrameFiller {
-    
-        public $width;
-        public $frame;
-        public $x;
-        public $y;
-        public $dir;
-        public $bit;
-        
-        //----------------------------------------------------------------------
-        public function __construct($width, &$frame)
-        {
-            $this->width = $width;
-            $this->frame = $frame;
-            $this->x = $width - 1;
-            $this->y = $width - 1;
-            $this->dir = -1;
-            $this->bit = -1;
-        }
-        
-        //----------------------------------------------------------------------
-        public function setFrameAt($at, $val)
-        {
-            $this->frame[$at['y']][$at['x']] = chr($val);
-        }
-        
-        //----------------------------------------------------------------------
-        public function getFrameAt($at)
-        {
-            return ord($this->frame[$at['y']][$at['x']]);
-        }
-        
-        //----------------------------------------------------------------------
-        public function next()
-        {
-            do {
-            
-                if($this->bit == -1) {
-                    $this->bit = 0;
-                    return array('x'=>$this->x, 'y'=>$this->y);
-                }
-
-                $x = $this->x;
-                $y = $this->y;
-                $w = $this->width;
-
-                if($this->bit == 0) {
-                    $x--;
-                    $this->bit++;
-                } else {
-                    $x++;
-                    $y += $this->dir;
-                    $this->bit--;
-                }
-
-                if($this->dir < 0) {
-                    if($y < 0) {
-                        $y = 0;
-                        $x -= 2;
-                        $this->dir = 1;
-                        if($x == 6) {
-                            $x--;
-                            $y = 9;
-                        }
-                    }
-                } else {
-                    if($y == $w) {
-                        $y = $w - 1;
-                        $x -= 2;
-                        $this->dir = -1;
-                        if($x == 6) {
-                            $x--;
-                            $y -= 8;
-                        }
-                    }
-                }
-                if($x < 0 || $y < 0) return null;
-
-                $this->x = $x;
-                $this->y = $y;
-
-            } while(ord($this->frame[$y][$x]) & 0x80);
-                        
-            return array('x'=>$x, 'y'=>$y);
-        }
-        
-    } ;
-    
-    //##########################################################################    
-    
-    class QRencode {
-    
-        public $casesensitive = true;
-        public $eightbit = false;
-        
-        public $version = 0;
-        public $size = 3;
-        public $margin = 4;
-        
-        public $structured = 0; // not supported yet
-        
-        public $level = QR_ECLEVEL_L;
-        public $hint = QR_MODE_8;
-        
-        //----------------------------------------------------------------------
-        public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
-        {
-            $enc = new QRencode();
-            $enc->size = $size;
-            $enc->margin = $margin;
-            
-            switch ($level.'') {
-                case '0':
-                case '1':
-                case '2':
-                case '3':
-                        $enc->level = $level;
-                    break;
-                case 'l':
-                case 'L':
-                        $enc->level = QR_ECLEVEL_L;
-                    break;
-                case 'm':
-                case 'M':
-                        $enc->level = QR_ECLEVEL_M;
-                    break;
-                case 'q':
-                case 'Q':
-                        $enc->level = QR_ECLEVEL_Q;
-                    break;
-                case 'h':
-                case 'H':
-                        $enc->level = QR_ECLEVEL_H;
-                    break;
-            }
-            
-            return $enc;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeRAW($intext, $outfile = false) 
-        {
-            $code = new QRcode();
-
-            if($this->eightbit) {
-                $code->encodeString8bit($intext, $this->version, $this->level);
-            } else {
-                $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
-            }
-            
-            return $code->data;
-        }
-
-        //----------------------------------------------------------------------
-        public function encode($intext, $outfile = false) 
-        {
-            $code = new QRcode();
-
-            if($this->eightbit) {
-                $code->encodeString8bit($intext, $this->version, $this->level);
-            } else {
-                $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
-            }
-            
-            QRtools::markTime('after_encode');
-            
-            if ($outfile!== false) {
-                file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));
-            } else {
-                return QRtools::binarize($code->data);
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodePNG($intext, $outfile = false,$saveandprint=false) 
-        {
-            try {
-            
-                ob_start();
-                $tab = $this->encode($intext);
-                $err = ob_get_contents();
-                ob_end_clean();
-                
-                if ($err != '')
-                    QRtools::log($outfile, $err);
-                
-                $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
-                
-                QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
-            
-            } catch (Exception $e) {
-            
-                QRtools::log($outfile, $e->getMessage());
-            
-            }
-        }
-    }
-
-

+ 10 - 0
SE/superedit-POKAZ_OFERTY_AKTUALNE_FUNC.php

@@ -3655,6 +3655,12 @@ class PokazOfertyController {
 			}
 		}
 		if (count($sqlSearch) <= 0) return false;
+		if (!array_key_exists('TVC', $this->id_options_to_srv)) {
+			$sqlSearch[] = "g.`ID_TVC`='0'";
+		}
+		if (!array_key_exists('TEL', $this->id_options_to_srv)) {
+			$sqlSearch[] = "g.`ID_TEL`='0'";
+		}
 		$sqlSearch = implode(" and ", $sqlSearch);
 
 		$offersIds = array_values($this->id_options_to_srv);
@@ -5270,6 +5276,9 @@ class Services_Converter {
 				if ($v_srv->ID_OFFERS <= 0) {
 					$this->add_error("Brak numeru oferty przy usłudze ID=" . $v_srv->ID . ": " . $v_srv->NAME_LIST_SERVICES);
 				}
+				if ($v_srv->A_STATUS == 'OFF_SOFT') {
+					$this->add_error("Usługa ID=" . $v_srv->ID . " typu '{$v_srv->NAME_LIST_SERVICES}' została zablokowana statusem 'OFF_SOFT' ");
+				}
 			}
 
 			$srv_map = $this->get_srv_map_by_deal($old_deal_id);
@@ -7706,6 +7715,7 @@ class Column_ses_voip_a extends Column_ses_x_a {
 		$this->_data['ID_DOMAINS'] = '';// nazwa zewnetrzenego systemu
 		$this->_data['ID_DOMAINS_PACKET_ID'] = '';// ID z zewnetrzenego systemu
 		$this->_data['S_TECHNOLOGY'] = '';
+		$this->_data['S_ADDRESS_STREET'] = '';
 
 		$this->_data_from_offer = array();
 		$this->_data_from_offer []= 'VOIP_FAX2EMAIL';

+ 129 - 0
SE/superedit-PROCES_MENU.php

@@ -0,0 +1,129 @@
+<?php
+
+Lib::loadClass('TypespecialVariable');
+
+function PROCES_MENU() {
+
+	$taskMsgs = array();
+	$taskErrors = array();
+
+	$task = V::get('_task', '', $_REQUEST);
+	switch ($task) {
+		case 'TYPESPECIAL': {
+			$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+			header("Content-type: application/json");
+
+			$fld = V::get('fld', '', $_GET);
+			switch ($fld) {
+				case '_user_id': {
+					$typeSpecialUserId = TypespecialVariable::getInstance(-1, '__USER_ID');
+					if (!$typeSpecialUserId) {
+						$jsonData = new stdClass();
+						$jsonData->message = "TypeSpecial '__USER_ID' not exists";
+						echo json_encode($jsonData);
+						exit;
+					}
+
+					$query = V::get('q', '', $_REQUEST);
+					$rawRows = null;
+					$jsonData = array();
+					$queryParams = array();
+					$rows = $typeSpecialUserId->getValuesWithExports($query, $queryParams);
+					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
+					foreach ($rows as $kID => $vItem) {
+						$itemJson = new stdClass();
+						$itemJson->id = $vItem->id;
+						$itemJson->name = $vItem->param_out;
+						if (!empty($vItem->exports)) {
+							$itemJson->exports = $vItem->exports;
+						}
+						$jsonData[] = $itemJson;
+					}
+					echo json_encode($jsonData);
+					break;
+				}
+				case 'ProcesMenu__Proces_filtr_id': {
+					$typeSpecialProces = TypespecialVariable::getInstance(-1, '__PROCES');
+					if (!$typeSpecialProces) {
+						$jsonData = new stdClass();
+						$jsonData->message = "TypeSpecial '__PROCES' not exists";
+						echo json_encode($jsonData);
+						exit;
+					}
+
+					$query = V::get('q', '', $_REQUEST);
+					$rawRows = null;
+					$jsonData = array();
+					$queryParams = array();
+					$rows = $typeSpecialProces->getValuesWithExports($query, $queryParams);
+					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
+					foreach ($rows as $kID => $vItem) {
+						$itemJson = new stdClass();
+						$itemJson->id = $vItem->id;
+						$itemJson->name = $vItem->param_out;
+						if (!empty($vItem->exports)) {
+							$itemJson->exports = $vItem->exports;
+						}
+						$jsonData[] = $itemJson;
+					}
+					echo json_encode($jsonData);
+					break;
+				}
+				case 'ProcesMenu__Zasob_filtr_id': {
+					$typeSpecialZasob = TypespecialVariable::getInstance(-1, '__ZASOB');
+					if (!$typeSpecialZasob) {
+						$jsonData = new stdClass();
+						$jsonData->message = "TypeSpecial '__ZASOB' not exists";
+						echo json_encode($jsonData);
+						exit;
+					}
+
+					$query = V::get('q', '', $_REQUEST);
+					$rawRows = null;
+					$jsonData = array();
+					$queryParams = array();
+					$rows = $typeSpecialZasob->getValuesWithExports($query, $queryParams);
+					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
+					foreach ($rows as $kID => $vItem) {
+						$itemJson = new stdClass();
+						$itemJson->id = $vItem->id;
+						$itemJson->name = $vItem->param_out;
+						if (!empty($vItem->exports)) {
+							$itemJson->exports = $vItem->exports;
+						}
+						$jsonData[] = $itemJson;
+					}
+					echo json_encode($jsonData);
+					break;
+				}
+			}
+			exit;
+		}
+		case 'PROCES_FOR_TABLE': {
+			$tblId = V::get('tblId', 0, $_REQUEST, 'int');
+			$userAcl = User::getAcl();
+			$usedProcesInitIds = $userAcl->getUsedProcesInitIds($tblId);
+			//print_r($usedProcesInitIds);
+			$userProcesIdsCSV = implode(",", $usedProcesInitIds);
+			$url = $_SERVER['SCRIPT_URI'];
+			$url = substr($url, 0, strrpos($url, '/'));
+			$url .= "/procesy5.php?task=CRM_PROCES&filtr_id={$userProcesIdsCSV}&filtr_ids=%2B&filtr_ob=%2B&filtr_img=%2B";
+			//echo $url; exit;
+			if (!headers_sent()) {
+				header('HTTP/1.1 303 See Other');
+				header('Location: '.$url);
+			} else {
+				?>
+				<script type="text/javascript">
+	window.location.href='<?php echo $url; ?>';
+				</script>
+				<noscript>
+					<meta http-equiv="refresh" content="0;url=<?php echo $url; ?>" />
+				</noscript>
+				<p><a href="<?php echo $url; ?>">dalej</a></p>
+				<?php
+			}
+			exit;
+		}
+	}
+}

+ 474 - 58
SE/superedit-USERS2_WINDYKACJA_STATUS.php

@@ -34,7 +34,7 @@ function USERS2_WINDYKACJA_STATUS() {
 			if ($user_id > 0) {
 				$user = WindykacjaStatsModel::get_user_by_id($user_id);
 				if (!$user) {
-					echo'<p style="color:red">'."Użytkownik nie istnieje.".'</p>';
+					echo'<p style="color:red">'."Użytkownik nie istnieje lub brak uprawnień.".'</p>';
 				} else {
 					WindykacjaView::zadluzenia($user);
 					return;
@@ -43,12 +43,20 @@ function USERS2_WINDYKACJA_STATUS() {
 				echo'<p style="color:red">'."Bledne dane.".'</p>';
 			}
 		}
+		else if ($task == 'zestawienie_vectra_zadluzenia') {
+			WindykacjaView::zestawienie_vectra_zadluzenia();
+			exit;
+		}
+		else if ($task == 'zestawienie_vectra_nadplaty') {
+			WindykacjaView::zestawienie_vectra_nadplaty();
+			exit;
+		}
 		else if ($task == 'wezwanie') {
 			$user_id = V::get('user_id', 0, $_REQUEST, 'int');
 			if ($user_id > 0) {
 				$user = WindykacjaStatsModel::get_user_by_id($user_id);
 				if (!$user) {
-					echo'<p style="color:red">'."Użytkownik nie istnieje.".'</p>';
+					echo'<p style="color:red">'."Użytkownik nie istnieje lub brak uprawnień.".'</p>';
 				} else {
 					WindykacjaView::wezwanie($user, $user->PAY_TERM);
 					return;
@@ -62,7 +70,7 @@ function USERS2_WINDYKACJA_STATUS() {
 			if ($user_id > 0) {
 				$user = WindykacjaStatsModel::get_user_by_id($user_id);
 				if (!$user) {
-					echo'<p style="color:red">'."Użytkownik nie istnieje.".'</p>';
+					echo'<p style="color:red">'."Użytkownik nie istnieje lub brak uprawnień.".'</p>';
 				} else {
 					WindykacjaView::wezwanie_ostateczne($user, $user->PAY_TERM);
 					return;
@@ -76,7 +84,7 @@ function USERS2_WINDYKACJA_STATUS() {
 			if ($user_id > 0) {
 				$user = WindykacjaStatsModel::get_user_by_id($user_id);
 				if (!$user) {
-					echo'<p style="color:red">'."Użytkownik nie istnieje.".'</p>';
+					echo'<p style="color:red">'."Użytkownik nie istnieje lub brak uprawnień.".'</p>';
 				} else {
 					WindykacjaView::task_bok_rozwiazanie_umowy($user);
 					return;
@@ -90,7 +98,7 @@ function USERS2_WINDYKACJA_STATUS() {
 			if ($user_id > 0) {
 				$user = WindykacjaStatsModel::get_user_by_id($user_id);
 				if (!$user) {
-					echo'<p style="color:red">'."Użytkownik nie istnieje.".'</p>';
+					echo'<p style="color:red">'."Użytkownik nie istnieje lub brak uprawnień.".'</p>';
 				} else {
 					WindykacjaView::task_bok_rozwiazanie_umowy_print($user, V::get('id_koresp', 0, $_REQUEST, 'int'));
 					return;
@@ -156,7 +164,7 @@ function USERS2_WINDYKACJA_STATUS() {
 	if ($user_id > 0) {
 		$user = WindykacjaStatsModel::get_user_by_id($user_id);
 		if (!$user) {
-			echo'<p>'."Użytkownik nie istnieje.".'</p>';
+			echo'<p>'."Użytkownik nie istnieje lub brak uprawnień.".'</p>';
 			return;
 		}
 
@@ -1882,6 +1890,334 @@ body{font-family:arial;}
 		self::wezwanie($user, $wezwanie_termin, true);
 	}
 
+	public static function zestawienie_vectra_nadplaty() {
+		$usersList = array();
+		$db = DB::getDB();
+		$sql_select = "
+				c.`ID` as ID
+				, c.`ID` as id_users
+				, c.`P_NAME`
+				, c.`P_NAME_SECOND`
+				, c.`P_ADDRESS_STREET`
+				, c.`P_ADDRESS_HOME`
+				, c.`P_ADDRESS_HOUSE`
+				, c.`P_ADDRESS_CITY`
+				, c.`P_ADDRESS_POST_CODE`
+				, c.`P_ADDRESS_REGION`
+				, c.`P_PESEL`
+				, c.`P_PHONE`
+				, c.`P_OTHER_DOC`
+				, c.`user_mail_contact`
+				, c.`is_firma`
+				, w.`ID` as WINDYKACJA_ID
+				, w.`ID_BILLING_USERS`
+				, w.`A_STATUS`
+				, w.`A_STATUS_UPDATE_DATE`
+				, w.`USER_PAY_TERM_ADD`
+				, w.`L_APPOITMENT_DATE`
+				, w.`L_APPOITMENT_USER`
+				, w.`L_APPOITMENT_INFO`
+				, w.`PAY_DATE`
+				, w.`PAY_DATE_FIRST_FVAT`
+				, w.`PAY_TERM`
+				, w.`PAY_SALDO`
+				, w.`PAY_FVAT`
+				, w.`wezwanie1_DATE`
+				, w.`wezwanie2_DATE`
+				, w.`ID_KORESP`
+				, w.`LAST_PAY_DATE`
+				, w.`BAD_ADDRESS`
+				, c.`STATUS`
+				, c.`BILLING_OWNER`
+				, w.`NR_SPRAWY_KRD`
+				, w.`NR_SPRAWY_SAD`
+				, w.`NR_SPRAWY_KOMORNIK`
+				, w.`LAST_FVAT_PAY_TERM`
+		";
+		$sqlWhereAdd = "
+			and (w.`LAST_FVAT_PAY_TERM`>='2014-12-01'
+				or (	w.`LAST_FVAT_PAY_TERM`='0000-00-00'
+					and w.`LAST_FVAT_SELL_DATE`>='2014-12-01'
+				)
+			)
+			and c.`ID_BILLING_PREFIXES` in('0','1')
+			and c.`BILLING_OWNER` in('1')
+		";
+		$sql = "select {$sql_select}
+			from `USERS2_WINDYKACJA_STATUS` as w
+				join `COMPANIES` as c on(c.`ID`=w.`ID_BILLING_USERS`)
+			where c.`A_ADM_COMPANY`='19994_PODMIOT_Vectra_wlasciciel'
+				{$sqlWhereAdd}
+		";
+		if (V::get('DBG_SQL', '', $_GET)) {
+			header('Content-Type: text/plain; charset=utf-8');
+			echo $sql;
+			exit;
+		}
+		$res = $db->query($sql);
+		if ($db->has_errors()) {
+			print_r($db->get_errors());
+			die('die L.' . __LINE__);
+		}
+		while ($r = $db->fetch($res)) {
+			$usersList[$r->ID_BILLING_USERS] = $r;
+		}
+		if (V::get('DBG_ILE', '', $_GET)) {
+			echo '<p>ilosc: ' . count($usersList) . '</p>' . '<pre style="max-height:200px;overflow:auto">';
+				print_r($usersList);
+			echo '</pre>';
+			exit;
+		}
+		if (V::get('DBG_IDS', '', $_GET)) {
+			header('Content-Type: text/plain; charset=utf-8');
+			echo 'ilosc: ' . count($usersList) . "\n";
+			echo implode("\n", array_keys($usersList));
+			exit;
+		}
+		$limit = V::get('DBG_LOOP_LIMIT', 100000, $_GET, 'int');
+		if(V::get('DBG_LOOP_LIMIT', 0, $_GET, 'int')){echo "Loimit: {$limit}\n";}
+		$date_limit = V::get('DATE_LIMIT', date("Y-m-d"), $_GET);
+		$date_limit_from = '2014-12-01';
+		$csvFileName = "Zestawienie-nadplaty-do-{$date_limit}";
+		header('Content-Type: text/csv; charset=utf-8');
+		header("Content-Disposition: attachment; filename={$csvFileName}.csv");
+		$showCsvHeader = true;
+		foreach ($usersList as $userId => $user) {
+			$billing_docs = WindykacjaStatsModel::get_bill_dosc_by_date($user, $date_limit);
+			$billing_docs->sort_docs();
+			$saldo = $billing_docs->get_saldo();
+			if ($saldo <= 0) {
+				continue;
+			}
+			if(V::get('DBG_LOOP', '', $_GET)){echo "{$userId}:{$saldo}\n";}
+			$incomeDocs = $billing_docs->getLastIncomeDocsForSaldo($saldo);
+			if(V::get('DBG_LOOP', '', $_GET)){print_r($incomeDocs);echo "\n";}
+			//WindykacjaStatsModel::update_doc_number($incomeDocs);
+
+			$out_tbl = array();
+			foreach ($incomeDocs as $v_fvat) {
+				$out_tr = array();
+				$out_tr['ID'] = $v_fvat['ID'];
+				$out_tr['nr'] = $v_fvat['NUMBER'] . '/' . $v_fvat['ID_BILLING_PREFIXES'];
+				$out_tr['wplata'] = number_format($v_fvat['MA'], 2, '.', '');
+				$out_tr['data'] = $v_fvat['BILL_DATE'];
+				$out_tr['pozostalo'] = number_format($v_fvat['MA_POZOSTALO'], 2, '.', '');
+				array_push($out_tbl, $out_tr);// add to the begining
+			}
+
+			{// csv
+				$csvLine = array();
+				$csvLine[] = '"id klienta"';
+				$csvLine[] = '"nr dokumentu"';
+				$csvLine[] = '"kwota brutto"';
+				$csvLine[] = '"data wpłaty"';
+				$csvLine[] = '"pozostało"';
+				if ($showCsvHeader) {
+					echo implode(';', $csvLine) . ";\n";
+					$showCsvHeader = false;
+				}
+				foreach ($out_tbl as $tr) {
+					$csvLine = array();
+					$csvLine[] = '"' . $userId . '"';
+					$csvLine[] = '"' . $tr['nr'] . '"';
+					$csvLine[] = '"' . $tr['wplata'] . '"';
+					$csvLine[] = '"' . $tr['data'] . '"';
+					$csvLine[] = '"' . $tr['pozostalo'] . '"';
+					echo implode(';', $csvLine) . ";\n";
+				}
+			}
+			//echo '<pre style="max-height:200px;overflow:auto">incomeDocs: ';print_r($incomeDocs);echo'</pre>';
+			//echo '<pre style="max-height:200px;overflow:auto">ilosc('.count($out_tbl).') ' . "client({$userId}): ";print_r($out_tbl);echo'</pre>';
+			if (--$limit < 0) {
+				echo '<br>BREAK';
+				break;
+			}
+		}
+		exit;
+	}
+
+	public static function zestawienie_vectra_zadluzenia() {
+		$usersList = array();
+		$db = DB::getDB();
+		$sql_select = "
+				c.`ID` as ID
+				, c.`ID` as id_users
+				, c.`P_NAME`
+				, c.`P_NAME_SECOND`
+				, c.`P_ADDRESS_STREET`
+				, c.`P_ADDRESS_HOME`
+				, c.`P_ADDRESS_HOUSE`
+				, c.`P_ADDRESS_CITY`
+				, c.`P_ADDRESS_POST_CODE`
+				, c.`P_ADDRESS_REGION`
+				, c.`P_PESEL`
+				, c.`P_PHONE`
+				, c.`P_OTHER_DOC`
+				, c.`user_mail_contact`
+				, c.`is_firma`
+				, w.`ID` as WINDYKACJA_ID
+				, w.`ID_BILLING_USERS`
+				, w.`A_STATUS`
+				, w.`A_STATUS_UPDATE_DATE`
+				, w.`USER_PAY_TERM_ADD`
+				, w.`L_APPOITMENT_DATE`
+				, w.`L_APPOITMENT_USER`
+				, w.`L_APPOITMENT_INFO`
+				, w.`PAY_DATE`
+				, w.`PAY_DATE_FIRST_FVAT`
+				, w.`PAY_TERM`
+				, w.`PAY_SALDO`
+				, w.`PAY_FVAT`
+				, w.`wezwanie1_DATE`
+				, w.`wezwanie2_DATE`
+				, w.`ID_KORESP`
+				, w.`LAST_PAY_DATE`
+				, w.`BAD_ADDRESS`
+				, c.`STATUS`
+				, c.`BILLING_OWNER`
+				, w.`NR_SPRAWY_KRD`
+				, w.`NR_SPRAWY_SAD`
+				, w.`NR_SPRAWY_KOMORNIK`
+				, w.`LAST_FVAT_PAY_TERM`
+		";
+		$sqlWhereAdd = "
+			and (w.`LAST_FVAT_PAY_TERM`>='2014-12-01'
+				or (	w.`LAST_FVAT_PAY_TERM`='0000-00-00'
+					and w.`LAST_FVAT_SELL_DATE`>='2014-12-01'
+				)
+			)
+			and c.`ID_BILLING_PREFIXES` in('0','1')
+			and c.`BILLING_OWNER` in('1')
+		";
+		if (V::get('DBG_NUM', '', $_GET)) {// number of clients with fvat after 2014-12-01
+			$sqlWhereAdd = "
+				and (w.`LAST_FVAT_PAY_TERM`>='2014-12-01'
+					or (	w.`LAST_FVAT_PAY_TERM`='0000-00-00'
+						and w.`LAST_FVAT_SELL_DATE`>='2014-12-01'
+					)
+				)
+				and c.`ID_BILLING_PREFIXES` in('0','1')
+				and c.`BILLING_OWNER` in('1')
+			";
+		}
+		$sql = "select {$sql_select}
+			from `USERS2_WINDYKACJA_STATUS` as w
+				join `COMPANIES` as c on(c.`ID`=w.`ID_BILLING_USERS`)
+			where c.`A_ADM_COMPANY`='19994_PODMIOT_Vectra_wlasciciel'
+				{$sqlWhereAdd}
+		";
+		if (V::get('DBG_SQL', '', $_GET)) {
+			header('Content-Type: text/plain; charset=utf-8');
+			echo $sql;
+			exit;
+		}
+		$res = $db->query($sql);
+		if ($db->has_errors()) {
+			print_r($db->get_errors());
+			die();
+		}
+		while ($r = $db->fetch($res)) {
+			$usersList[$r->ID_BILLING_USERS] = $r;
+		}
+		if (V::get('DBG_ILE', '', $_GET)) {
+			echo '<p>ilosc: ' . count($usersList) . '</p>' . '<pre style="max-height:200px;overflow:auto">';
+				print_r($usersList);
+			echo '</pre>';
+			exit;
+		}
+		if (V::get('DBG_IDS', '', $_GET)) {
+			header('Content-Type: text/plain; charset=utf-8');
+			echo 'ilosc: ' . count($usersList) . "\n";
+			echo implode("\n", array_keys($usersList));
+			exit;
+		}
+		$limit = 10000;
+		$date_limit = V::get('DATE_LIMIT', date("Y-m-d"), $_GET);
+		$date_limit_from = '2014-12-01';
+		$csvFileName = "Zestawienie-zadluzenia-do-{$date_limit}";
+		header('Content-Type: text/csv; charset=utf-8');
+		header("Content-Disposition: attachment; filename={$csvFileName}.csv");
+		$showCsvHeader = true;
+		foreach ($usersList as $userId => $user) {
+			$billing_docs = WindykacjaStatsModel::get_bill_dosc_by_date($user, $date_limit);
+			$billing_docs->sort_docs();
+			$fvat_arr = $billing_docs->get_unpaid_fvat();
+			WindykacjaStatsModel::update_doc_number($fvat_arr);
+
+			if (V::get('DBG_LAST_FVAT_TERM', '', $_GET)) {
+				$lastFvatDoc = $billing_docs->get_last_fvat_doc();
+				if ($lastFvatDoc) {
+					echo '<p>lastFvatDoc:</p><pre style="max-height:200px;overflow:auto">';
+						print_r($lastFvatDoc);
+					echo '</pre>';
+					exit;
+				}
+			}
+
+			$user->hasActiveDeal = 0;
+			$sql = "select sum(t.`DEALS_ACTIVE`) as activeDeals
+				from `temp_DEALS_STATUS` as t
+				where t.`DEALS_ACTIVE`=1
+					and t.`ID_BILLING_USERS`='{$userId}'
+			";
+			$res = $db->query($sql);
+			if ($db->num_rows($res) > 0) {
+				$user->hasActiveDeal = 1;
+			}
+
+			$out_tbl = array();
+			foreach ($fvat_arr as $v_fvat) {
+				if ($v_fvat['BILL_DATE'] < $date_limit_from || $v_fvat['BILL_DATE'] > $date_limit) {
+					//echo 'pomin fvat:'."\n";print_r($v_fvat);
+					continue;
+				}
+				$out_tr = array();
+				$out_tr['ID'] = $v_fvat['ID'];
+				$out_tr['nr'] = $v_fvat['NUMBER'] . '/' . $v_fvat['ID_BILLING_PREFIXES'];
+				$out_tr['winien'] = number_format($v_fvat['WINIEN'], 2, '.', '');
+				$out_tr['data'] = $v_fvat['BILL_DATE'];
+				$out_tr['termin'] = $v_fvat['PAYMENT_TERM'];
+				$out_tr['pozostalo'] = number_format($v_fvat['WINIEN_POZOSTALO'], 2, '.', '');
+				array_unshift($out_tbl, $out_tr);// add to the begining
+			}
+
+			{// csv
+				$csvLine = array();
+				$csvLine[] = '"id klienta"';
+				$csvLine[] = '"nr dokumentu"';
+				$csvLine[] = '"kwota brutto"';
+				$csvLine[] = '"data faktury"';
+				$csvLine[] = '"termin płatności"';
+				$csvLine[] = '"pozostało do zapłaty"';
+				$csvLine[] = '"status klienta (9=blokada)"';
+				$csvLine[] = '"aktywne uslugi"';
+				if ($showCsvHeader) {
+					echo implode(';', $csvLine) . ";\n";
+					$showCsvHeader = false;
+				}
+				foreach ($out_tbl as $tr) {
+					$csvLine = array();
+					$csvLine[] = '"' . $userId . '"';
+					$csvLine[] = '"' . $tr['nr'] . '"';
+					$csvLine[] = '"' . $tr['winien'] . '"';
+					$csvLine[] = '"' . $tr['data'] . '"';
+					$csvLine[] = '"' . $tr['termin'] . '"';
+					$csvLine[] = '"' . $tr['pozostalo'] . '"';
+					$csvLine[] = '"' . $user->STATUS . '"';
+					$csvLine[] = '"' . $user->hasActiveDeal . '"';
+					echo implode(';', $csvLine) . ";\n";
+				}
+			}
+			//echo '<pre style="max-height:200px;overflow:auto">fvat_arr: ';print_r($fvat_arr);echo'</pre>';
+			//echo '<pre style="max-height:200px;overflow:auto">ilosc('.count($out_tbl).') ' . "client({$userId}): ";print_r($out_tbl);echo'</pre>';
+			if (--$limit < 0) {
+				echo '<br>BREAK';
+				break;
+			}
+		}
+		exit;
+	}
+
 	public static function wezwanie(&$user, $wezwanie_termin, $wezwanie_ostateczne = false) {
 		$date_limit = date("Y-m-d");
 		$billing_docs = WindykacjaStatsModel::get_bill_dosc_by_date($user, $date_limit);
@@ -2136,6 +2472,37 @@ Informacja o zadłużeniu upubliczniona będzie w systemie KRD do dnia zapłaty
 		}
 	}
 
+	public static function getPowodyRezygnacji() {
+		// [895].[3888] - DEALS_TABLE.RODZAJ_DZIALANIA_HANDLOWEGO
+		$powody = array();
+		//	$powody['3226'] = "REZYGNACJA FINANSE";
+		//	$powody['3227'] = "REZYGNACJA SLABA OFERTA";
+		//	$powody['3121'] = "REZYGNACJA WYPROWADZKA";
+		//	$powody['3228'] = "REZYGNACJA PROBLEMY TECHNICZNE";
+		//	$powody['3230'] = "REZYGNACJA WYJAZD";
+		//	$powody['3229'] = "REZYGNACJA ZLA OBSLUGA BOK";
+		//	$powody['3123'] = "REZYGNACJA CESJA";
+		//	$powody['3119'] = "BRAK-BOK (Inne)";
+		//	$powody['4188'] = "UMOWA_BEZPOSREDNIA";
+		//	$powody['4189'] = "UMOWA_POSREDNIA";
+		//	$powody['4190'] = "TELEMARKETING";
+		$powody['4192'] = "REZYGNACJA ZMIANA OPERATORA";
+		$powody['4193'] = "REZYGNACJA WYPROWADZKA";
+		$powody['4194'] = "REZYGNACJA NIEZADOWOLENIE";
+		$powody['4195'] = "REZYGNACJA CESJA";
+		//$powody['4196'] = "REZYGNACJA FINANSE";
+		$powody['4197'] = "REZYGNACJA SLABA OFERTA";
+		$powody['4198'] = "REZYGNACJA PROBLEMY TECHNICZNE";
+		$powody['4199'] = "REZYGNACJA ZLA OBSLUGA BOK";
+		$powody['4200'] = "WYPOWIEDZENIE PRZEZ OPERATORA ZA DLUGI";
+		//	$powody['4201'] = "UMOWA W BOK ZWYCZAJNA";
+		//	$powody['4202'] = "REZYGNACJA WYJAZD";
+		//	$powody['4191'] = "BRAK-BOK (Inne)";
+		$powody['19803'] = "REZYGNACJA_Z_PRZEJSCIEM_DO_VECTRA";
+		$powody['4213'] = "REZYGNACJA INNE";
+		return $powody;
+	}
+
 	/**
 	 * @params $user
 	 * @params $id_koresp
@@ -2183,28 +2550,7 @@ Informacja o zadłużeniu upubliczniona będzie w systemie KRD do dnia zapłaty
 		}
 
 		$arg_values = array();
-		$arg_values['powod'] = array();// [774].[800] - USERS2_DEALS.RODZAJ_DZIALANIA_HANDLOWEGO
-//		$arg_values['powod']['3226'] = "Finansowe";
-//		$arg_values['powod']['3227'] = "Niesatysfakcjonująca oferta";
-//		$arg_values['powod']['3121'] = "Przeprowadzka";
-//		$arg_values['powod']['3228'] = "Problemy techniczne/awarie";
-//		$arg_values['powod']['3230'] = "Wyjazd";
-//		$arg_values['powod']['3229'] = "Zła obsługa BOK/DT";
-//		$arg_values['powod']['3119'] = "Inne";
-
-		// [895].[3888] - DEALS_TABLE.RODZAJ_DZIALANIA_HANDLOWEGO
-		$arg_values['powod']['4192'] = "REZYGNACJA ZMIANA OPERATORA";
-		$arg_values['powod']['4193'] = "REZYGNACJA WYPROWADZKA";
-		$arg_values['powod']['4194'] = "REZYGNACJA NIEZADOWOLENIE";
-		$arg_values['powod']['4195'] = "REZYGNACJA CESJA";
-		//$arg_values['powod']['4196'] = "REZYGNACJA FINANSE";
-		$arg_values['powod']['4197'] = "REZYGNACJA SLABA OFERTA";
-		$arg_values['powod']['4198'] = "REZYGNACJA PROBLEMY TECHNICZNE";
-		$arg_values['powod']['4199'] = "REZYGNACJA ZLA OBSLUGA BOK";
-		$arg_values['powod']['4200'] = "WYPOWIEDZENIE PRZEZ OPERATORA ZA DLUGI";
-		//$arg_values['powod']['4202'] = "REZYGNACJA WYJAZD";
-		// $arg_values['powod']['4191'] = "BRAK-BOK (Inne)";
-		$arg_values['powod']['4213'] = "REZYGNACJA INNE";
+		$arg_values['powod'] = self::getPowodyRezygnacji();
 
 		$com = new stdClass();
 		if ($user->BILLING_OWNER == 2) {
@@ -2316,33 +2662,7 @@ function frm_bok_rozwiazanie_umowy(frm){
 			$arg_values['nr_umowy'][$v_deal['ID']] = $v_deal['ID'] . ' (Nr umowy: ' . $v_deal['P_DEALNUMBER'] . ', ' . $v_deal['P_DEALDATE'] . ' - ' . $v_deal['P_DEALDATE_TERM'] . ')';
 		}
 
-		$arg_values['powod'] = array();// [774].[800] - USERS2_DEALS.RODZAJ_DZIALANIA_HANDLOWEGO
-//		$arg_values['powod']['3226'] = "REZYGNACJA FINANSE";
-//		$arg_values['powod']['3227'] = "REZYGNACJA SLABA OFERTA";
-//		$arg_values['powod']['3121'] = "REZYGNACJA WYPROWADZKA";
-//		$arg_values['powod']['3228'] = "REZYGNACJA PROBLEMY TECHNICZNE";
-//		$arg_values['powod']['3230'] = "REZYGNACJA WYJAZD";
-//		$arg_values['powod']['3229'] = "REZYGNACJA ZLA OBSLUGA BOK";
-//		$arg_values['powod']['3123'] = "REZYGNACJA CESJA";
-//		$arg_values['powod']['3119'] = "BRAK-BOK (Inne)";
-
-		// [895].[3888] - DEALS_TABLE.RODZAJ_DZIALANIA_HANDLOWEGO
-		//	$arg_values['powod']['4188'] = "UMOWA_BEZPOSREDNIA";
-		//	$arg_values['powod']['4189'] = "UMOWA_POSREDNIA";
-		//	$arg_values['powod']['4190'] = "TELEMARKETING";
-		$arg_values['powod']['4192'] = "REZYGNACJA ZMIANA OPERATORA";
-		$arg_values['powod']['4193'] = "REZYGNACJA WYPROWADZKA";
-		$arg_values['powod']['4194'] = "REZYGNACJA NIEZADOWOLENIE";
-		$arg_values['powod']['4195'] = "REZYGNACJA CESJA";
-		//$arg_values['powod']['4196'] = "REZYGNACJA FINANSE";
-		$arg_values['powod']['4197'] = "REZYGNACJA SLABA OFERTA";
-		$arg_values['powod']['4198'] = "REZYGNACJA PROBLEMY TECHNICZNE";
-		$arg_values['powod']['4199'] = "REZYGNACJA ZLA OBSLUGA BOK";
-		$arg_values['powod']['4200'] = "WYPOWIEDZENIE PRZEZ OPERATORA ZA DLUGI";
-		//	$arg_values['powod']['4201'] = "UMOWA W BOK ZWYCZAJNA";
-		//$arg_values['powod']['4202'] = "REZYGNACJA WYJAZD";
-		// $arg_values['powod']['4191'] = "BRAK-BOK (Inne)";
-		$arg_values['powod']['4213'] = "REZYGNACJA INNE";
+		$arg_values['powod'] = self::getPowodyRezygnacji();
 
 		// validate
 		if ($args['temin_odlaczenia'] == '') {
@@ -2433,6 +2753,9 @@ class BillingDocs {
 
 	public function add_bill_doc($data, $type, $h) {
 		$bill_doc = new BillingDoc($type, $h);
+		if ('FVAT' == $type && '0000-00-00' == $data) {
+			$data = $h['BILL_DATE'];
+		}
 		$this->_docs[$data][] = $bill_doc;
 		if ($data <= date("Y-m-d")) {
 			$this->_saldo += $bill_doc->get_saldo();
@@ -2490,6 +2813,34 @@ class BillingDocs {
 		return $fvat_arr;
 	}
 
+	public function getLastIncomeDocsForSaldo($saldoLimit) {
+		$today_date = date("Y-m-d");
+		$incomeDocs = array();
+		$break = false;
+		$saldo_dates_keys = array_keys($this->_docs);
+		$saldo_dates_keys = array_reverse($saldo_dates_keys);
+		$saldo_curr = 0;
+		foreach ($saldo_dates_keys as $k_data) {
+			if ($k_data > $today_date) continue;
+			$v_saldo_arr = $this->_docs[$k_data];
+			foreach ($v_saldo_arr as $k_ind => $v_doc) {
+				if (in_array($v_doc->get_type(), array('WB_MASS','KP'))) {
+					$h = $v_doc->get_data();
+					$h['MA_POZOSTALO'] = round($h['MA'], 2);
+					$saldo_curr += round($h['MA'], 2);
+					if ($saldo_curr >= $saldoLimit) {
+						$h['MA_POZOSTALO'] -= $saldo_curr - $saldoLimit;
+						$break = true;
+					}
+					$incomeDocs[] = $h;
+				}
+				if ($break) break;
+			}
+			if ($break) break;
+		}
+		return $incomeDocs;
+	}
+
 	public function get_last_pay_doc() {
 		$last_pay_doc = null;
 		$today_date = date("Y-m-d");
@@ -2507,6 +2858,23 @@ class BillingDocs {
 		return $last_pay_doc;
 	}
 
+	public function get_last_fvat_doc() {
+		$last_fvat_doc = null;
+		$today_date = date("Y-m-d");
+		$break = false;
+		foreach ($this->_docs as $k_data => $v_saldo_arr) {
+			if ($k_data > $today_date) continue;
+			foreach ($v_saldo_arr as $k_ind => $v_doc) {
+				if (in_array($v_doc->get_type(), array('FVAT'))) {
+					$last_fvat_doc = $v_doc;
+					break;
+				}
+			}
+			if ($break) break;
+		}
+		return $last_fvat_doc;
+	}
+
 }
 
 
@@ -2667,8 +3035,10 @@ class WindykacjaStatsHelper {
 	 */
 	public static function update_stats(&$user, &$billing_docs) {
 		$data_arr = array();
-		if ($user->A_STATUS_UPDATE_DATE >= date("Y-m-d")) {
-			return;
+		if (!V::get('DBG_LAST_FVAT_PAY_TERM', '', $_GET)) {
+			if ($user->A_STATUS_UPDATE_DATE >= date("Y-m-d")) {
+				return;
+			}
 		}
 		$saldo = $billing_docs->get_saldo();
 		$data_arr["A_STATUS_UPDATE_DATE"] = date("Y-m-d");
@@ -2690,6 +3060,12 @@ class WindykacjaStatsHelper {
 		$data_arr["PAY_SALDO"] = $saldo;
 		$data_arr["PAY_FVAT"] = 0;
 		$data_arr["PAY_DATE_FIRST_FVAT"] = '0000-00-00';
+		$lastFvatDoc = $billing_docs->get_last_fvat_doc();
+		if(V::get('DBG_LAST_FVAT_PAY_TERM', '', $_GET)){echo'<pre>lastFvatDoc: ';print_r($lastFvatDoc);echo'</pre>';}
+		if ($lastFvatDoc) {
+			$data_arr["LAST_FVAT_PAY_TERM"] = $lastFvatDoc->get('PAYMENT_TERM');
+			$data_arr["LAST_FVAT_SELL_DATE"] = $lastFvatDoc->get('SELL_DATE');
+		}
 		if ($saldo <= 0) {
 			$fvat_arr = $billing_docs->get_unpaid_fvat();
 			$data_arr["PAY_FVAT"] = count($fvat_arr);
@@ -3271,11 +3647,21 @@ class WindykacjaStatsHelper {
 	}
 
 	public static function get_status_count() {
+		$sql_where_and_arr = array();
+		$usrAclGroups = User::getLdapGroupsNames();
+		$usrAclGroups[] = '';
+		$sqlUsrAclGroups = "'" . implode("','", $usrAclGroups) . "'";
+		$sql_where_and_arr[] = "a.`A_ADM_COMPANY` in({$sqlUsrAclGroups})";
+		$sql_where_and_arr[] = "a.`A_CLASSIFIED` in({$sqlUsrAclGroups})";
+		$sqlWhereAdd = " and " . implode(" and ", $sql_where_and_arr);
+
 		$ret = array();
 		$db = DB::getDB();
 		$sql = " select w.`A_STATUS`, count(1) as cnt
 				, sum(IF(w.`PAY_SALDO`<0, w.`PAY_SALDO`, 0)) as suma_zaleglosci
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
+			where 1=1 {$sqlWhereAdd}
 			group by w.`A_STATUS` 
 		";
 		$res = $db->query($sql);
@@ -3287,10 +3673,12 @@ class WindykacjaStatsHelper {
 				, count(1) as cnt
 				, sum(IF(w.`PAY_SALDO`<0, w.`PAY_SALDO`, 0)) as suma_zaleglosci
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				w.`PAY_SALDO`<0
 				and w.`PAY_DATE`!='0000-00-00'
 				and w.`PAY_DATE`<DATE_SUB(NOW(), INTERVAL 36 MONTH)
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3301,11 +3689,13 @@ class WindykacjaStatsHelper {
 				, count(1) as cnt
 				, sum(IF(w.`PAY_SALDO`<0, w.`PAY_SALDO`, 0)) as suma_zaleglosci
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				w.`PAY_SALDO`<0
 				and w.`PAY_DATE`!='0000-00-00'
 				and w.`PAY_DATE`<DATE_SUB(NOW(), INTERVAL 33 MONTH)
 				and w.`PAY_DATE`>DATE_SUB(NOW(), INTERVAL 36 MONTH)
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3316,11 +3706,13 @@ class WindykacjaStatsHelper {
 				, count(1) as cnt
 				, sum(IF(w.`PAY_SALDO`<0, w.`PAY_SALDO`, 0)) as suma_zaleglosci
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				w.`PAY_SALDO`<0
 				and w.`A_STATUS` in('wezwanie1', 'waiting-wezwanie2', 'wezwanie2', 'waiting-krd')
 				and ( w.`LAST_PHONE_STATUS_DATE`='0000-00-00'
-					or w.`LAST_PHONE_STATUS_DATE`<DATE_SUB(NOW(), INTERVAL 3 MONTH) )
+					or w.`LAST_PHONE_STATUS_DATE`<DATE_SUB(NOW(), INTERVAL 14 DAY) )
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3331,10 +3723,12 @@ class WindykacjaStatsHelper {
 				, count(1) as cnt
 				, sum(IF(w.`PAY_SALDO`<0, w.`PAY_SALDO`, 0)) as suma_zaleglosci
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				w.`PAY_SALDO`<0
 				-- and w.`A_STATUS` in('wezwanie1', 'waiting-wezwanie2', 'wezwanie2', 'waiting-krd')
 				and w.`BAD_ADDRESS`>0
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3347,8 +3741,10 @@ class WindykacjaStatsHelper {
 				, sum(IF(w.`PAY_SALDO`<0, 1, 0)) as cnt_stan_minus
 				, sum(IF(w.`PAY_SALDO`<0, w.`PAY_SALDO`, 0)) as suma_zaleglosci
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				w.`A_STATUS`='WAITING'
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3362,11 +3758,13 @@ class WindykacjaStatsHelper {
 				, sum(IF(w.`NR_SPRAWY_KOMORNIK`!='', 1, 0)) as cnt_komornik
 				, sum(IF(w.`L_APPOITMENT_INFO`!='', 1, 0)) as cnt_ustalenia
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				(w.`NR_SPRAWY_SAD`!=''
 					or w.`NR_SPRAWY_KOMORNIK`!=''
 					or w.`L_APPOITMENT_INFO`!=''
 				)
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3379,8 +3777,10 @@ class WindykacjaStatsHelper {
 				, count(1) as cnt
 				, sum(IF(w.`NR_SPRAWY_KOMORNIK`!='', 1, 0)) as cnt_komornik
 			from  `USERS2_WINDYKACJA_STATUS` as w
+				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where
 				w.`A_STATUS`='sad'
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {
@@ -3398,6 +3798,13 @@ class WindykacjaStatsModel {
 	public static function _parse_query($q) {
 		$sql_where = '';
 		$sql_where_and_arr = array();
+
+		$usrAclGroups = User::getLdapGroupsNames();
+		$usrAclGroups[] = '';
+		$sqlUsrAclGroups = "'" . implode("','", $usrAclGroups) . "'";
+		$sql_where_and_arr[] = "a.`A_ADM_COMPANY` in({$sqlUsrAclGroups})";
+		$sql_where_and_arr[] = "a.`A_CLASSIFIED` in({$sqlUsrAclGroups})";
+
 		$filter_selected = WindykacjaStatsHelper::get_filter_selected();
 		if ($filter_selected) {
 			if ($filter_selected == 'po-terminie') {
@@ -3634,6 +4041,14 @@ class WindykacjaStatsModel {
 		$ret = null;
 		if ($id <= 0) return $ret;
 
+		$sql_where_and_arr = array();
+		$usrAclGroups = User::getLdapGroupsNames();
+		$usrAclGroups[] = '';
+		$sqlUsrAclGroups = "'" . implode("','", $usrAclGroups) . "'";
+		$sql_where_and_arr[] = "a.`A_ADM_COMPANY` in({$sqlUsrAclGroups})";
+		$sql_where_and_arr[] = "a.`A_CLASSIFIED` in({$sqlUsrAclGroups})";
+		$sqlWhereAdd = " and " . implode(" and ", $sql_where_and_arr);
+
 		$sql_select = self::get_sql_users_select();
 		$sql_where = "a.`id_users`='{$id}'";
 		$db = DB::getDB();
@@ -3642,6 +4057,7 @@ class WindykacjaStatsModel {
 				left join `BILLING_USERS` as bu on(bu.`ID`=w.`ID_BILLING_USERS`)
 				left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
 			where {$sql_where}
+				{$sqlWhereAdd}
 		";
 		$res = $db->query($sql);
 		if ($r = $db->fetch($res)) {