Fixed typos in installer translation files, fixed translations in dashboard procedures.
[fa-stable.git] / includes / main.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 include_once($path_to_root . "/includes/db/connect_db.inc");
13
14 include_once($path_to_root . "/admin/db/transactions_db.inc");
15 include_once($path_to_root . "/includes/types.inc");
16 include_once($path_to_root . "/includes/references.inc");
17 include_once($path_to_root . "/includes/db/comments_db.inc");
18 include_once($path_to_root . "/includes/db/sql_functions.inc");
19 include_once($path_to_root . "/includes/db/audit_trail_db.inc");
20
21 include_once($path_to_root . "/admin/db/users_db.inc");
22 include_once($path_to_root . "/includes/ui/ui_view.inc");
23 include_once($path_to_root . "/includes/ui/ui_controls.inc");
24
25 $page_nested = -1;
26 // static js files path
27 $js_path = $path_to_root.'/js/';
28 // standard external js scripts included in all files
29 $js_static = array('JsHttpRequest.js', 'behaviour.js', 'utils.js', 'inserts.js');
30 // additional js source included in header
31 $js_lib = $js_userlib = array();
32
33 function page($title, $no_menu=false, $is_index=false, $onload="", $js="", $script_only=false, $css='')
34 {
35
36         global $path_to_root, $page_security, $page_nested;
37
38         if (++$page_nested) return;
39
40         $hide_menu = $no_menu;
41
42         include_once($path_to_root . "/includes/page/header.inc");
43
44         page_header($title, $no_menu, $is_index, $onload, $js, $css);
45         check_page_security($page_security);
46 //      error_box();
47         if($script_only) {
48                 echo '<noscript>';
49                 echo display_heading(_('This page is usable only with javascript enabled browsers.'));
50                 echo '</noscript>';
51                 div_start('_page_body', null, true);
52         } else {
53                 div_start('_page_body'); // whole page content for ajax reloading
54         }
55 }
56
57 function end_page($no_menu=false, $is_index=false, $final_screen=false, $type_no=0, $trans_no=0)
58 {
59         global $path_to_root, $page_nested;
60
61         if ($page_nested-- > 0) return;
62
63         if (!$is_index && function_exists('hyperlink_back'))
64                 hyperlink_back(true, $no_menu, $type_no, $trans_no, $final_screen);
65         div_end();      // end of _page_body section
66
67         include_once($path_to_root . "/includes/page/footer.inc");
68         page_footer($no_menu, $is_index);
69 }
70
71 function cache_js_file($fpath, $text) 
72 {
73         global $SysPrefs;
74
75         if (!$SysPrefs->go_debug) $text = js_compress($text);
76
77     $file = force_open($fpath);
78         if (!$file) return false;
79         if (!fwrite($file, $text)) return false;
80         return fclose($file);
81
82 }
83
84 /*
85         Open file for writing with creration of subfolders if needed.
86 */
87 function force_open($fname)
88 {
89         $file = pathinfo($fname);
90
91         $path = $fname[0] == '/' ? '/' : '';
92         $tree = explode('/', $file['dirname']);
93         foreach($tree as $level) {
94                 $path .= $level;
95                 if (!file_exists($path)) {
96                         if (!mkdir($path)) {
97                                 return null;
98                         }
99                 }
100                 $path .= '/';
101         }
102         return fopen($fname, 'w');
103 }
104
105 function add_js_file($filename) 
106 {
107           global $js_static;
108
109           $search = array_search($filename, $js_static);
110           if ($search === false || $search === null) // php>4.2.0 returns null
111                 $js_static[] = $filename;       
112 }
113
114 function add_js_ufile($filename) 
115 {
116           global $js_userlib;
117
118           $search = array_search($filename, $js_userlib);
119           if ($search === false || $search === null) // php>4.2.0 returns null
120                 $js_userlib[] = $filename;
121 }
122
123 function add_js_source($text) 
124 {
125           global $js_lib;
126
127           $search = array_search($text, $js_lib);
128           if ($search === false || $search === null) // php>4.2.0 returns null
129                 $js_lib[] = $text;
130 }
131
132 /**
133  * Compresses the Javascript code for more efficient delivery.
134  * copyright (c) 2005 by Jared White & J. Max Wilson
135  * http://www.xajaxproject.org
136  * Added removing comments from output.
137  * Warning: Fails on RegExp with quotes - use new RegExp() in this case.
138  */
139 function js_compress($sJS)
140 {
141         //remove windows cariage returns
142         $sJS = str_replace("\r","",$sJS);
143         
144         //array to store replaced literal strings
145         $literal_strings = array();
146         
147         //explode the string into lines
148         $lines = explode("\n",$sJS);
149         //loop through all the lines, building a new string at the same time as removing literal strings
150         $clean = "";
151         $inComment = false;
152         $literal = "";
153         $inQuote = false;
154         $escaped = false;
155         $quoteChar = "";
156         
157         for($i=0;$i<count($lines);$i++)
158         {
159                 $line = $lines[$i];
160                 $inNormalComment = false;
161         
162                 //loop through line's characters and take out any literal strings, replace them with ___i___ where i is the index of this string
163                 $len = strlen($line);
164                 for($j=0;$j<$len;$j++)
165                 {
166                         $c = $line[$j];         // this is _really_ faster than subst
167                         $d = $c.$line[$j+1];
168         
169                         //look for start of quote
170                         if(!$inQuote && !$inComment)
171                         {
172                                 //is this character a quote or a comment
173                                 if(($c=="\"" || $c=="'") && !$inComment && !$inNormalComment)
174                                 {
175                                         $inQuote = true;
176                                         $inComment = false;
177                                         $escaped = false;
178                                         $quoteChar = $c;
179                                         $literal = $c;
180                                 }
181                                 else if($d=="/*" && !$inNormalComment)
182                                 {
183                                         $inQuote = false;
184                                         $inComment = true;
185                                         $escaped = false;
186                                         $quoteChar = $d;
187                                         $literal = $d;  
188                                         $j++;   
189                                 }
190                                 else if($d=="//") //ignore string markers that are found inside comments
191                                 {
192                                         $inNormalComment = true;
193                                         $clean .= $c;
194                                 }
195                                 else
196                                 {
197                                         $clean .= $c;
198                                 }
199                         }
200                         else //allready in a string so find end quote
201                         {
202                                 if($c == $quoteChar && !$escaped && !$inComment)
203                                 {
204                                         $inQuote = false;
205                                         $literal .= $c;
206         
207                                         //subsitute in a marker for the string
208                                         $clean .= "___" . count($literal_strings) . "___";
209         
210                                         //push the string onto our array
211                                         array_push($literal_strings,$literal);
212         
213                                 }
214                                 else if($inComment && $d=="*/")
215                                 {
216                                         $inComment = false;
217                                         $literal .= $d;
218         
219                                         //subsitute in a marker for the string
220                                         $clean .= "___" . count($literal_strings) . "___";
221         
222                                         //push the string onto our array
223                                         array_push($literal_strings,$literal);
224         
225                                         $j++;
226                                 }
227                                 else if($c == "\\" && !$escaped)
228                                         $escaped = true;
229                                 else
230                                         $escaped = false;
231         
232                                 $literal .= $c;
233                         }
234                 }
235                 if($inComment) $literal .= "\n";
236                 $clean .= "\n";
237         }
238         //explode the clean string into lines again
239         $lines = explode("\n",$clean);
240         
241         //now process each line at a time
242         for($i=0;$i<count($lines);$i++)
243         {
244                 $line = $lines[$i];
245         
246                 //remove comments
247                 $line = preg_replace("/\/\/(.*)/","",$line);
248         
249                 //strip leading and trailing whitespace
250                 $line = trim($line);
251         
252                 //remove all whitespace with a single space
253                 $line = preg_replace("/\s+/"," ",$line);
254         
255                 //remove any whitespace that occurs after/before an operator
256                 $line = preg_replace("/\s*([!\}\{;,&=\|\-\+\*\/\)\(:])\s*/","\\1",$line);
257         
258                 $lines[$i] = $line;
259         }
260         
261         //implode the lines
262         $sJS = implode("\n",$lines);
263         
264         //make sure there is a max of 1 \n after each line
265         $sJS = preg_replace("/[\n]+/","\n",$sJS);
266         
267         //strip out line breaks that immediately follow a semi-colon
268         $sJS = preg_replace("/;\n/",";",$sJS);
269         
270         //curly brackets aren't on their own
271         $sJS = preg_replace("/[\n]*\{[\n]*/","{",$sJS);
272         
273         //finally loop through and replace all the literal strings:
274         for($i=0;$i<count($literal_strings);$i++) {
275             if (strpos($literal_strings[$i],"/*")!==false) 
276                 $literal_strings[$i]= '';
277                 $sJS = str_replace("___".$i."___",$literal_strings[$i],$sJS);
278         }
279         return $sJS;
280 }
281
282 /*
283         Check if file can be updated, restoring subdirectories 
284         if needed. Returns 1 when no confilcts, -1 when file exists and is writable
285 */
286 function check_write($path)
287 {
288         if ($path == ''//|| $path == '.' || $path == '..'
289         ) return 0;
290
291         return is_writable($path) ? (is_dir($path) ? 1 : -1) 
292                 : (is_file($path) ? 0 : ($path == '.' || $path == '..' ? 0 : check_write(dirname($path))));
293 }
294
295 /*
296         Copies set of files. When $strict is set
297         also removes files from the $to which 
298         does not exists in $from directory but arelisted in $flist.
299 */
300 function copy_files($flist, $from, $to, $strict=false)
301 {
302         foreach ($flist as $file) {
303                 if (file_exists($from.'/'.$file)) {
304                         if (!copy_file($file, $from, $to))
305                                 return false;
306                 } else if ($strict) {
307                                 unlink($to.'/'.$file);
308                 }
309         }
310         return true;
311 }
312
313 /*
314         Copies file from base to target directory, restoring subdirectories 
315         if needed.
316 */
317 function copy_file($file, $from, $to)
318 {
319
320         if (!is_dir(dirname($file=='.' ? $to : ($to.'/'.$file)))) {
321                 if (!copy_file(dirname($file), null, $to))
322                         return false;
323         }
324         if (!$from) {
325         //              error_log( 'dodanie katalogu '.$to.'/'.$file);
326                 return @mkdir($file=='.' ? $to : ($to.'/'.$file));
327         }
328         else {
329         //              error_log( 'skopiowanie '.$to.'/'.$file);
330                 return @copy($from.'/'.$file, $to.'/'.$file);
331         }
332 }
333 /*
334         Search for file, looking first for company specific version, then for 
335         version provided by any extension module, finally in main FA directory.
336         Also adds include path for any related files, and sets $local_path_to_root 
337         to enable local translation domains.
338         
339         Returns found file path or null.
340 */
341 function find_custom_file($rep)
342 {
343         global $installed_extensions, $path_to_root, $local_path_to_root;
344
345         // customized per company version
346         $path = company_path();
347         $file = $path.$rep;
348         if (file_exists($file)) {
349                 // add local include path
350                 $local_path_to_root = $path;
351                 set_include_path(dirname($file).PATH_SEPARATOR.get_include_path());
352                 return $file;
353         }
354         // file added by active extension modules
355         if (count($installed_extensions) > 0)
356         {
357                 $extensions = $installed_extensions;
358                 foreach ($extensions as $ext)
359                         if (($ext['active'] && $ext['type'] == 'extension')) {
360                                 $path = $path_to_root.'/'.$ext['path'];
361                                 $file = $path.$rep;
362                                 if (file_exists($file)) {
363                                         set_include_path($path.PATH_SEPARATOR.get_include_path());
364                                         $local_path_to_root = $path;
365                                         return $file;
366                                 }
367                         }
368         }
369         // standard location
370         $file = $path_to_root.$rep;
371         if (file_exists($file))
372                 return $file;
373
374         return null;
375 }
376 /*
377         
378         Protect against directory traversal.
379         Changes all not POSIX compatible chars to underscore.
380 */
381 function clean_file_name($filename) {
382     $filename = str_replace(chr(0), '', $filename);
383     return preg_replace('/[^a-zA-Z0-9.\-_]/', '_', $filename);
384 }
385
386 /*
387         Simple random password generator.
388 */
389 function generate_password()
390 {
391         if (PHP_VERSION >= '5.3')
392                 $bytes = openssl_random_pseudo_bytes(8, $cstrong);
393         else
394                 $bytes = sprintf("08%x", mt_rand(0,0xffffffff));
395
396         return  base64_encode($bytes);
397 }
398
399 if (!function_exists('array_fill_keys')) // since 5.2
400 {
401         function array_fill_keys($keys, $value)
402         {
403                 return array_combine($keys, array_fill(count($keys), $value));
404         }
405 }
406