]> git.mxchange.org Git - friendica-addons.git/blob - jappixmini/jappix/php/functions-manager.php
Merge branch '3.6-release'
[friendica-addons.git] / jappixmini / jappix / php / functions-manager.php
1 <?php
2
3 /*
4
5 Jappix - An open social platform
6 These are the PHP functions for Jappix manager
7
8 -------------------------------------------------
9
10 License: AGPL
11 Authors: Vanaryon, Mathieui, olivierm, Vinilox
12 Last revision: 15/01/12
13
14 */
15
16 // The function to check an user is admin
17 function isAdmin($user, $password) {
18         // Read the users.xml file
19         $array = getUsers();
20         
21         // No data?
22         if(empty($array))
23                 return false;
24         
25         // Our user is set and valid?
26         if(isset($array[$user]) && ($array[$user] == $password))
27                 return true;
28         
29         // Not authorized
30         return false;
31 }
32
33 // Checks if a file is a valid image
34 function isImage($file) {
35         // This is an image
36         if(preg_match('/^(.+)(\.)(png|jpg|jpeg|gif|bmp)$/i', $file))
37                 return true;
38         
39         return false;
40 }
41
42 // Puts a marker on the current opened manager tab
43 function currentTab($current, $page) {
44         if($current == $page)
45                 echo ' class="tab-active"';
46 }
47
48 // Checks all the storage folders are writable
49 function storageWritable() {
50         // Read the directory content
51         $dir = JAPPIX_BASE.'/store/';
52         $scan = scandir($dir);
53         
54         // Writable marker
55         $writable = true;
56         
57         // Check that each folder is writable
58         foreach($scan as $current) {
59                 // Current folder
60                 $folder = $dir.$current;
61                 
62                 // A folder is not writable?
63                 if(!preg_match('/^\.(.+)/', $current) && !is_writable($folder)) {
64                         // Try to change the folder rights
65                         chmod($folder, 0777);
66                         
67                         // Check it again!
68                         if(!is_writable($folder))
69                                 $writable = false;
70                 }
71         }
72         
73         return $writable;
74 }
75
76 // Removes a given directory (with all sub-elements)
77 function removeDir($dir) {
78         // Can't open the dir
79         if(!$dh = @opendir($dir))
80                 return;
81         
82         // Loop the current dir to remove its content
83         while(false !== ($obj = readdir($dh))) {
84                 // Not a "real" directory
85                 if(($obj == '.') || ($obj == '..'))
86                         continue;
87                 
88                 // Not a file, remove this dir
89                 if(!@unlink($dir.'/'.$obj))
90                         removeDir($dir.'/'.$obj);
91         }
92         
93         // Close the dir and remove it!
94         closedir($dh);
95         @rmdir($dir);
96 }
97
98 // Copies a given directory (with all sub-elements)
99 function copyDir($source, $destination) {
100         // This is a directory
101         if(is_dir($source)) {
102                 // Create the target directory
103                 @mkdir($destination);
104                 $directory = dir($source);
105                 
106                 // Append the source directory content into the target one
107                 while(FALSE !== ($readdirectory = $directory->read())) {
108                         if(($readdirectory == '.') || ($readdirectory == '..'))
109                                 continue;
110                         
111                         $PathDir = $source.'/'.$readdirectory;
112                         
113                         // Recursive copy
114                         if(is_dir($PathDir)) {
115                                 copyDir($PathDir, $destination.'/'.$readdirectory);
116                                 
117                                 continue;
118                         }
119                         
120                         copy($PathDir, $destination.'/'.$readdirectory);
121                 }
122                 
123                 // Close the source directory
124                 $directory->close();
125         }
126         
127         // This is a file
128         else
129                 copy($source, $destination);
130 }
131
132 // Gets the total size of a directory
133 function sizeDir($dir) {
134         $size = 0;
135         
136         foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $file)
137                 $size += $file->getSize();
138         
139         return $size;
140 }
141
142 // Set the good unity for a size in bytes
143 function numericToMonth($id) {
144         $array = array(
145                         1 => T_("January"),
146                         2 => T_("February"),
147                         3 => T_("March"),
148                         4 => T_("April"),
149                         5 => T_("May"),
150                         6 => T_("June"),
151                         7 => T_("July"),
152                         8 => T_("August"),
153                         9 => T_("September"),
154                         10 => T_("October"),
155                         11 => T_("November"),
156                         12 =>T_( "December")
157                       );
158         
159         return $array[$id];
160 }
161
162 // Extracts the version number with a version ID
163 function versionNumber($id) {
164         // First, extract the number string from the [X]
165         $extract = preg_replace('/^(.+)\[(\S+)\]$/', '$2', $id);
166         $dev = false;
167         
168         // Second extract: ~ (when this is a special version, like ~dev)
169         if(strrpos($extract, '~') !== false) {
170                 $dev = true;
171                 $extract = preg_replace('/^([^~])~(.+)$/', '$1', $extract);
172         }
173         
174         // Convert [X.X.X] into a full number
175         $extract = preg_replace('/[^0-9]/', '', $extract);
176         
177         // Add missing items to [X.X.X]
178         $missing = 3 - strlen($extract.'');
179         if($missing > 0)
180                 $extract = $extract.(str_repeat('0', $missing));
181         
182         // Allows updates for dev versions
183         if($dev)
184                 $extract = $extract - 1;
185         
186         return intval($extract);
187 }
188
189 // Checks for new Jappix updates
190 function newUpdates($force) {
191         // No need to check if developer mode
192         if(isDeveloper())
193                 return false;
194         
195         $cache_path = JAPPIX_BASE.'/store/updates/version.xml';
196         
197         // No cache, obsolete one or refresh forced
198         if(!file_exists($cache_path) || (file_exists($cache_path) && (time() - (filemtime($cache_path)) >= 86400)) || $force) {
199                 // Get the content
200                 $last_version = read_url('http://codingteam.net/project/jappix/upload/briefcase/version.xml');
201                 
202                 // Write the content
203                 file_put_contents($cache_path, $last_version);
204         }
205         
206         // Read from the cache
207         else
208                 $last_version = file_get_contents($cache_path);
209         
210         // Parse the XML
211         $xml = @simplexml_load_string($last_version);
212         
213         // No data?
214         if($xml === FALSE)
215                 return false;
216         
217         // Get the version numbers
218         $current_version = getVersion();
219         $last_version = $xml->id;
220         
221         // Check if we have the latest version
222         $current_version = versionNumber($current_version);
223         $last_version = versionNumber($last_version);
224         
225         if($current_version < $last_version)
226                 return true;
227         
228         return false;
229 }
230
231 // Gets the Jappix update informations
232 function updateInformations() {
233         // Get the XML file content
234         $data = file_get_contents(JAPPIX_BASE.'/store/updates/version.xml');
235         
236         // Transform the XML content into an array
237         $array = array();
238         
239         // No XML?
240         if(!$data)
241                 return $array;
242         
243         $xml = new SimpleXMLElement($data);
244         
245         // Parse the XML to add it to the array
246         foreach($xml->children() as $this_child) {
247                 // Get the node name
248                 $current_name = $this_child->getName();
249                 
250                 // Push it to the array, with a basic HTML encoding
251                 $array[$current_name] = str_replace('\n', '<br />', $this_child);
252         }
253         
254         // Return this array
255         return $array;
256 }
257
258 // Processes the Jappix update from an external package
259 function processUpdate($url) {
260         // Archive path
261         $name = md5($url).'.zip';
262         $update_dir = $dir_base.'store/updates/';
263         $path = JAPPIX_BASE.'/store/updates/'.$name;
264         $extract_to = $update_dir.'jappix/';
265         $store_tree = JAPPIX_BASE.'/php/store-tree.php';
266         
267         // We must get the archive from the server
268         if(!file_exists($path)) {
269                 echo('<p>» '.T_("Downloading package...").'</p>');
270                 
271                 // Open the packages
272                 $local = fopen($path, 'w');
273                 $remote = fopen($url, 'r');
274                 
275                 // Could not open a socket?!
276                 if(!$remote) {
277                         echo('<p>» '.T_("Aborted: socket error!").'</p>');
278                         
279                         // Remove the broken local archive
280                         unlink($path);
281                         
282                         return false;
283                 }
284                 
285                 // Read the file
286                 while(!feof($remote)) {
287                         // Get the buffer
288                         $buffer = fread($remote, 1024);
289                         
290                         // Any error?
291                         if($buffer == 'Error.') {
292                                 echo('<p>» '.T_("Aborted: buffer error!").'</p>');
293                                 
294                                 // Remove the broken local archive
295                                 unlink($path);
296                                 
297                                 return false;
298                         }
299                         
300                         // Write the buffer to the file
301                         fwrite($local, $buffer);
302                         
303                         // Flush the current buffer
304                         ob_flush();
305                         flush();
306                 }
307                 
308                 // Close the files
309                 fclose($local);
310                 fclose($remote);
311         }
312         
313         // Then, we extract the archive
314         echo('<p>» '.T_("Extracting package...").'</p>');
315         
316         try {
317                 $zip = new ZipArchive;
318                 $zip_open = $zip->open($path);
319                 
320                 if($zip_open === TRUE) {
321                         $zip->extractTo($update_dir);
322                         $zip->close();
323                 }
324                 
325                 else {
326                         echo('<p>» '.T_("Aborted: could not extract the package!").'</p>');
327                         
328                         // Remove the broken source folder
329                         removeDir($to_remove);
330                         
331                         return false;
332                 }
333         }
334         
335         // PHP does not provide Zip archives support
336         catch(Exception $e) {
337                 echo('<p>» '.T_("Aborted: could not extract the package!").'</p>');
338                 
339                 // Remove the broken source folder
340                 removeDir($to_remove);
341                 
342                 return false;
343         }
344         
345         // Remove the ./store dir from the source directory
346         removeDir($extract_to.'store/');
347         
348         // Then, we remove the Jappix system files
349         echo('<p>» '.T_("Removing current Jappix system files...").'</p>');
350         
351         // Open the general directory
352         $dir_base = JAPPIX_BASE.'/';
353         $scan = scandir($dir_base);
354         
355         // Filter the scan array
356         $scan = array_diff($scan, array('.', '..', '.svn', 'store'));
357         
358         // Check all the files are writable
359         foreach($scan as $scanned) {
360                 // Element path
361                 $scanned_current = $dir_base.$scanned;
362                 
363                 // Element not writable
364                 if(!is_writable($scanned_current)) {
365                         // Try to change the element rights
366                         chmod($scanned_current, 0777);
367                         
368                         // Check it again!
369                         if(!is_writable($scanned_current)) {
370                                 echo('<p>» '.T_("Aborted: everything is not writable!").'</p>');
371                                 
372                                 return false;
373                         }
374                 }
375         }
376         
377         // Process the files deletion
378         foreach($scan as $current) {
379                 $to_remove = $dir_base.$current;
380                 
381                 // Remove folders
382                 if(is_dir($to_remove))
383                         removeDir($to_remove);
384                 
385                 // Remove files
386                 else
387                         unlink($to_remove);
388         }
389         
390         // Move the extracted files to the base
391         copyDir($extract_to, $dir_base);
392         
393         // Remove the source directory
394         removeDir($extract_to);
395         
396         // Regenerates the store tree
397         if(file_exists($store_tree)) {
398                 echo('<p>» '.T_("Regenerating storage folder tree...").'</p>');
399                 
400                 // Call the special regeneration script
401                 include($store_tree);
402         }
403         
404         // Remove the version package
405         unlink($path);
406         
407         // The new version is now installed!
408         echo('<p>» '.T_("Jappix is now up to date!").'</p>');
409         
410         return true;
411 }
412
413 // Returns an array with the biggest share folders
414 function shareStats() {
415         // Define some stuffs
416         $path = JAPPIX_BASE.'/store/share/';
417         $array = array();
418         
419         // Open the directory
420         $scan = scandir($path);
421         
422         // Loop the share files
423         foreach($scan as $current) {
424                 if(is_dir($path.$current) && !preg_match('/^(\.(.+)?)$/i', $current))
425                         array_push($array, $current);
426         }
427         
428         return $array;
429 }
430
431 // Returns the largest share folders
432 function largestShare($array, $number) {
433         // Define some stuffs
434         $path = JAPPIX_BASE.'/store/share/';
435         $size_array = array();
436         
437         // Push the results in an array
438         foreach($array as $current)
439                 $size_array[$current] = sizeDir($path.$current);
440         
441         // Sort this array
442         arsort($size_array);
443         
444         // Select the first biggest values
445         $size_array = array_slice($size_array, 0, $number);
446         
447         return $size_array;
448 }
449
450 // Returns the others statistics array
451 function otherStats() {
452         // Fill the array with the values
453         $others_stats = array(
454                                 T_("Backgrounds") => sizeDir(JAPPIX_BASE.'/store/backgrounds/'),
455                                 T_("Cache") => sizeDir(JAPPIX_BASE.'/store/cache/'),
456                                 T_("Logs") => sizeDir(JAPPIX_BASE.'/store/logs/'),
457                                 T_("Music") => sizeDir(JAPPIX_BASE.'/store/music/'),
458                                 T_("Share") => sizeDir(JAPPIX_BASE.'/store/share/'),
459                                 T_("Send") => sizeDir(JAPPIX_BASE.'/store/send/'),
460                                 T_("Updates") => sizeDir(JAPPIX_BASE.'/store/updates/')
461                              );
462         
463         // Sort this array
464         arsort($others_stats);
465         
466         return $others_stats;
467 }
468
469 // Gets the array of the visits stats
470 function getVisits() {
471         // New array
472         $array = array(
473                         'total' => 0,
474                         'daily' => 0,
475                         'weekly' => 0,
476                         'monthly' => 0,
477                         'yearly' => 0
478                       );
479         
480         // Read the data
481         $data = readXML('access', 'total');
482         
483         // Any data?
484         if($data) {
485                 // Initialize the visits reading
486                 $xml = new SimpleXMLElement($data);
487                 
488                 // Get the XML values
489                 $array['total'] = intval($xml->total);
490                 $array['stamp'] = intval($xml->stamp);
491                 
492                 // Get the age of the stats
493                 $age = time() - $array['stamp'];
494                 
495                 // Generate the time-dependant values
496                 $timed = array(
497                                 'daily' => 86400,
498                                 'weekly' => 604800,
499                                 'monthly' => 2678400,
500                                 'yearly' => 31536000
501                               );
502                 
503                 foreach($timed as $timed_key => $timed_value) {
504                         if($age >= $timed_value)
505                                 $array[$timed_key] = intval($array['total'] / ($age / $timed[$timed_key])).'';
506                         else
507                                 $array[$timed_key] = $array['total'].'';
508                 }
509         }
510         
511         return $array;
512 }
513
514 // Gets the array of the monthly visits
515 function getMonthlyVisits() {
516         // New array
517         $array = array();
518         
519         // Read the data
520         $data = readXML('access', 'months');
521         
522         // Get the XML file values
523         if($data) {
524                 // Initialize the visits reading
525                 $xml = new SimpleXMLElement($data);
526                 
527                 // Loop the visit elements
528                 foreach($xml->children() as $child) {
529                         // Get the current month ID
530                         $current_id = intval(preg_replace('/month_([0-9]+)/i', '$1', $child->getName()));
531                         
532                         // Get the current month name
533                         $current_name = numericToMonth($current_id);
534                         
535                         // Push it!
536                         $array[$current_name] = intval($child);
537                 }
538         }
539         
540         return $array;
541 }
542
543 // Purges the target folder content
544 function purgeFolder($folder) {
545         // Array of the folders to purge
546         $array = array();
547         
548         // We must purge all the folders?
549         if($folder == 'everything')
550                 array_push($array, 'cache', 'logs', 'send', 'updates');
551         else
552                 array_push($array, $folder);
553         
554         // All right, now we can empty it!
555         foreach($array as $current_folder) {
556                 // Scan the current directory
557                 $directory = JAPPIX_BASE.'/store/'.$current_folder.'/';
558                 $scan = scandir($directory);
559                 $scan = array_diff($scan, array('.', '..', '.svn', 'index.html'));
560                 
561                 // Process the files deletion
562                 foreach($scan as $current) {
563                         $remove_this = $directory.$current;
564                         
565                         // Remove folders
566                         if(is_dir($remove_this))
567                                 removeDir($remove_this);
568                         
569                         // Remove files
570                         else
571                                 unlink($remove_this);
572                 }
573         }
574 }
575
576 // Returns folder browsing informations
577 function browseFolder($folder, $mode) {
578         // Scan the target directory
579         $directory = JAPPIX_BASE.'/store/'.$folder;
580         $scan = scandir($directory);
581         $scan = array_diff($scan, array('.', '..', '.svn', 'index.html'));
582         $keep_get = keepGet('(s|b|k)', false);
583         
584         // Odd/even marker
585         $marker = 'odd';
586         
587         // Not in the root folder: show previous link
588         if(strpos($folder, '/') != false) {
589                 // Filter the folder name
590                 $previous_folder = substr($folder, 0, strrpos($folder, '/'));
591                 
592                 echo('<div class="one-browse previous manager-images"><a href="./?b='.$mode.'&s='.urlencode($previous_folder).$keep_get.'">'.T_("Previous").'</a></div>');
593         }
594         
595         // Empty or non-existing directory?
596         if(!count($scan) || !is_dir($directory)) {
597                 echo('<div class="one-browse '.$marker.' alert manager-images">'.T_("The folder is empty.").'</div>');
598                 
599                 return false;
600         }
601         
602         // Echo the browsing HTML code
603         foreach($scan as $current) {
604                 // Generate the item path$directory
605                 $path = $directory.'/'.$current;
606                 $file = $folder.'/'.$current;
607                 
608                 // Directory?
609                 if(is_dir($path)) {
610                         $type = 'folder';
611                         $href = './?b='.$mode.'&s='.urlencode($file).$keep_get;
612                         $target = '';
613                 }
614                 
615                 // File?
616                 else {
617                         $type = getFileType(getFileExt($path));
618                         $href = $path;
619                         $target = ' target="_blank"';
620                 }
621                 
622                 echo('<div class="one-browse '.$marker.' '.$type.' manager-images"><a href="'.$href.'"'.$target.'>'.htmlspecialchars($current).'</a><input type="checkbox" name="element_'.md5($file).'" value="'.htmlspecialchars($file).'" /></div>');
623                 
624                 // Change the marker
625                 if($marker == 'odd')
626                         $marker = 'even';
627                 else
628                         $marker = 'odd';
629         }
630         
631         return true;
632 }
633
634 // Removes selected elements (files/folders)
635 function removeElements() {
636         // Initialize the match
637         $elements_removed = false;
638         $elements_remove = array();
639         
640         // Try to get the elements to remove
641         foreach($_POST as $post_key => $post_value) {
642                 // Is a safe file?
643                 if(preg_match('/^element_(.+)$/i', $post_key) && isSafe($post_value)) {
644                         // Update the marker
645                         $elements_removed = true;
646                         
647                         // Get the real path
648                         $post_element = JAPPIX_BASE.'/store/'.$post_value;
649                         
650                         // Remove the current element
651                         if(is_dir($post_element))
652                                 removeDir($post_element);
653                         else if(file_exists($post_element))
654                                 unlink($post_element);
655                 }
656         }
657         
658         // Show a notification message
659         if($elements_removed)
660                 echo('<p class="info smallspace success">'.T_("The selected elements have been removed.").'</p>');
661         else
662                 echo('<p class="info smallspace fail">'.T_("You must select elements to remove!").'</p>');
663 }
664
665 // Returns users browsing informations
666 function browseUsers() {
667         // Get the users
668         $array = getUsers();
669         
670         // Odd/even marker
671         $marker = 'odd';
672         
673         // Echo the browsing HTML code
674         foreach($array as $user => $password) {
675                 // Filter the username
676                 $user = htmlspecialchars($user);
677                 
678                 // Output the code
679                 echo('<div class="one-browse '.$marker.' user manager-images"><span>'.$user.'</span><input type="checkbox" name="admin_'.md5($user).'" value="'.$user.'" /><div class="clear"></div></div>');
680                 
681                 // Change the marker
682                 if($marker == 'odd')
683                         $marker = 'even';
684                 else
685                         $marker = 'odd';
686         }
687 }
688
689 // Generates the logo form field
690 function logoFormField($id, $name) {
691         if(file_exists(JAPPIX_BASE.'/store/logos/'.$name.'.png'))
692                 echo '<span class="logo_links"><a class="remove manager-images" href="./?k='.urlencode($name).keepGet('k', false).'" title="'.T_("Remove this logo").'"></a><a class="view manager-images" href="./store/logos/'.$name.'.png" target="_blank" title="'.T_("View this logo").'"></a></span>';
693         else
694                 echo '<input id="logo_own_'.$id.'_location" type="file" name="logo_own_'.$id.'_location" accept="image/*" />';
695         
696         echo "\n";
697 }
698
699 // Reads the background configuration
700 function readBackground() {
701         // Read the background configuration XML
702         $background_data = readXML('conf', 'background');
703         
704         // Get the default values
705         $background_default = defaultBackground();
706         
707         // Stored data array
708         $background_conf = array();
709         
710         // Read the stored values
711         if($background_data) {
712                 // Initialize the background configuration XML data
713                 $background_xml = new SimpleXMLElement($background_data);
714                 
715                 // Loop the notice configuration elements
716                 foreach($background_xml->children() as $background_child)
717                         $background_conf[$background_child->getName()] = $background_child;
718         }
719         
720         // Checks no value is missing in the stored configuration
721         foreach($background_default as $background_name => $background_value) {
722                 if(!isset($background_conf[$background_name]) || empty($background_conf[$background_name]))
723                         $background_conf[$background_name] = $background_default[$background_name];
724         }
725         
726         return $background_conf;
727 }
728
729 // Writes the background configuration
730 function writeBackground($array) {
731         // Generate the XML data
732         $xml = '';
733         
734         foreach($array as $key => $value)
735                 $xml .= "\n".'  <'.$key.'>'.stripslashes(htmlspecialchars($value)).'</'.$key.'>';
736         
737         // Write this data
738         writeXML('conf', 'background', $xml);
739 }
740
741 // Generates a list of the available background images
742 function getBackgrounds() {
743         // Initialize the result array
744         $array = array();
745         
746         // Scan the background directory
747         $scan = scandir(JAPPIX_BASE.'/store/backgrounds/');
748         
749         foreach($scan as $current) {
750                 if(isImage($current))
751                         array_push($array, $current);
752         }
753         
754         return $array;
755 }
756
757 // Writes the notice configuration
758 function writeNotice($type, $simple) {
759         // Generate the XML data
760         $xml = 
761         '<type>'.$type.'</type>
762         <notice>'.stripslashes(htmlspecialchars($simple)).'</notice>'
763         ;
764         
765         // Write this data
766         writeXML('conf', 'notice', $xml);
767 }
768
769 ?>