Code

3a3a207680fd06851a4fbd2bcfd6afa4e6919983
[gosa.git] / gosa-core / update-gosa
1 #!/usr/bin/php5
2 <?php
4 define ("GOSA_HOME", dirname(__FILE__));
5 define ("LOCALE_DIR", GOSA_HOME."/locale");
6 define ("PLUGSTATE_DIR", GOSA_HOME."/state");
8 function print_usage()
9 {
10         ?>
11 update-gosa - class cache updated and plugin manager for GOsa
12 Usage: update-gosa install dsc     Install the plugin using the dsc information
13                                    placed in the plugin source directory.
15        update-gosa remove plugin   Remove the plugin named "plugin" from
16                                    the current configuration.
18        update-gosa lists           Lists installed plugins
20        update-gosa rescan-i18n     Rebuilds the translations
22        update-gosa rescan-classes  Rebuilds the class list
23        
24        update-gosa                 Shortcut for rescan-classes and rescan-i18n
25 <?php
26         exit (1);
27 }
30 /* Function to include all class_ files starting at a given directory base */
31 function get_classes($folder= ".")
32 {
33   static $base_dir= "";
34   static $result= array();
36   if ($base_dir == ""){
37     $base_dir= getcwd();
38   }
40   $currdir=getcwd();
41   if ($folder){
42     chdir("$folder");
43   }
45   $dh = opendir(".");
46   while(false !== ($file = readdir($dh))){
48     if (preg_match("/.*\.svn.*/", $file) ||
49         preg_match("/.*smarty.*/i",$file) ||
50         preg_match("/.*\.tpl.*/",$file) ||
51         ($file==".") ||($file =="..")){
52       continue;
53     }
55     /* Recurse through all "common" directories */
56     if (is_dir($file)){
57       get_classes($file);
58       continue;
59     }
61     /* Only take care about .inc and .php files... */
62     if (!(preg_match('/\.php$/', $file) || preg_match('/\.inc$/', $file))){
63       continue;
64     }
66     /* Include existing class_ files */
67     $contents= file($file);
68     foreach($contents as $line){
69       $line= chop($line);
70       if (preg_match('/^\s*class\s*\w.*$/', $line)){
71         $class= preg_replace('/^\s*class\s*(\w+).*$/', '\1', $line);
72         $result[$class]= preg_replace("%$base_dir/%", "", "$currdir/$folder/$file");
73       }
74     }
75   }
77   closedir($dh);
78   chdir($currdir);
80   return ($result);
81 }
84 function rescan_classes()
85 {
86         echo "Updating class cache...\n";
87         $class_mapping= get_classes();
88         $filename= GOSA_HOME."/include/class_location.inc";
90         /* Sanity checks */
91         if (!file_exists($filename) || is_writable($filename)) {
93             if (!$handle= fopen($filename, 'w')) {
94                  echo "Cannot open file \"$filename\" - aborted\n";
95                  exit (1);
96             }
98         } else {
99             echo "File \"$filename\" is not writable - aborted\n";
100             exit (2);
101         }
103         fwrite ($handle, "<?php\n\$class_mapping= array(\n");
104         foreach ($class_mapping as $key => $value){
105           fwrite ($handle, "                \"$key\" => \"$value\",\n");
106         }
107         fwrite ($handle, " );\n");
109         fclose($handle);
113 function rescan_i18n()
115         echo "Updating internationalization...\n";
116         $languages= array();
117         $size= strlen(LOCALE_DIR);
119         /* Get all available messages.po files, sort them for languages */
120         $dir= new RecursiveDirectoryIterator(LOCALE_DIR);
121         $all= new RecursiveIteratorIterator($dir);
122         foreach ( $all as $element ){
123                 if ($element->isFile() && preg_match('/\/LC_MESSAGES\/messages.po$/', $element->getPathname())){
124                         $lang= preg_replace('/^.*\/([^\/]+)\/LC_MESSAGES\/.*$/', '\1', $element);
125                         if (!isset($languages[$lang])){
126                                 $languages[$lang]= array();
127                         }
128                         $languages[$lang][]= substr($element->getPathName(), $size+1);
129                 }
130         }
132         /* For each language, merge the target .mo to the compiled directory. */
133         foreach ($languages as $language => $po_files){
134                 if (!is_dir(LOCALE_DIR."/compiled/${language}/LC_MESSAGES")){
135                         if (!mkdir (LOCALE_DIR."/compiled/${language}/LC_MESSAGES", 0755, TRUE)){
136                                 echo "Failed to create '".LOCALE_DIR."/compiled/${language}/LC_MESSAGES'- aborted";
137                                 exit (3);
138                         }
139                 }
141                 /* Cat all these po files into one single file */
142                 system ("(cd ".LOCALE_DIR." && msgcat ".implode(" ", $po_files)." > compiled/${language}/LC_MESSAGES/messages.po)", $val);
143                 if ($val != 0){
144                         echo "Merging of message files failed - aborted";
145                         exit (4);
146                 }
147                 system ("(cd ".LOCALE_DIR."/compiled/${language}/LC_MESSAGES && msgfmt -o messages.mo messages.po && rm messages.po)", $val);
148                 if ($val != 0){
149                         echo "Compiling of message files failed - aborted";
150                         exit (5);
151                 }
152         }
156 function parse_ini($file)
158         global $description, $provides, $depends;
160         $res= "";
161         if (file_exists($file)){
162                 $tmp= parse_ini_file($file, TRUE);
164                 if (isset($tmp['gosa-plugin'])){
165                         $plugin= &$tmp['gosa-plugin'];
166                         if (isset($plugin['name'])&& isset($plugin['description'])){
167                                 $res= $plugin['name'];
168                                 $provides[$res]= $plugin[$res];
169                                 $description[$res]= $plugin['description'];
170                                 if (isset($plugin['depends'])){
171                                         $depends[$res]= explode(',', preg_replace('/\s+/', '', $plugin['depends']));
172                                 }
173                         }
174                 }
175         }
177         return $res;
181 function dependency_check()
183         global $description, $provides, $depends;
185         foreach ($depends as $name => $pl_depends){
186                 foreach ($pl_depends as $pl){
187                         if (!in_array($pl, $provides)){
188                                 echo "! Error: plugin '$name' depends on '$pl' which is not provided by any plugin\n\n";
189                                 exit (1);
190                         }
191                 }
192         }
196 function load_plugins()
198         if (!is_dir(PLUGSTATE_DIR)){
199                 if (!mkdir (PLUGSTATE_DIR, 0755, TRUE)){
200                         echo "Cannot create plugstate dir '".PLUGSTATE_DIR."' - aborted\n";
201                         exit (2);
202                 }
203         }
204         $dir= new DirectoryIterator(PLUGSTATE_DIR);
205         foreach ($dir as $entry){
206                 if ($dir->isDir() && !preg_match('/^\./', $dir->__toString())){
207                         $file= $dir->getPathName()."/plugin.dsc";
208                         if (!parse_ini($file)){
209                                 echo "! Warning: plugin ".$dir->getPathName()." is missing declarations\n";
210                         }
211                 }
212         }
216 function list_plugins()
218         global $description;
219         $count= 0;
221         /* Load plugin list */
222         load_plugins();
224         /* Show plugins */
225         foreach ($description as $name => $dsc){
226                 if ($count == 0){
227                         echo "Plugin\t\t| Description\n";
228                         echo "------------------------------------------------------------------------\n";
229                 }
230                 echo "* $name\t\t| ".$dsc."\n";
231                 $count++;
232         }
234         /* Yell about non existing plugins... */
235         if ($count == 0){
236                 echo "No plugins found...\n\n";
237         } else {
238                 # Check for dependencies
239                 dependency_check();
240                 echo "\n";
241         }
245 function install_plugin($file)
247         global $description, $provides, $depends;
249         /* Load plugin list */
250         load_plugins();
252         /* Load .dsc file */
253         if (file_exists($file)){
254                 $tmp= parse_ini_file($file, TRUE);
256                 if (isset($tmp['gosa-plugin'])){
257                         $plugin= &$tmp['gosa-plugin'];
258                         if (isset($plugin['name'])&& isset($plugin['description'])){
259                                 $name= $plugin['name'];
260                                 $description= $plugin['description'];
261                                 $depends= array();
262                                 if (isset($plugin['depends'])){
263                                         $depends= explode(',', preg_replace('/\s+/', '', $plugin['depends']));
264                                 }
266                                 /* Already installed? */
267                                 if (isset($provides[$name])){
268                                         echo "! Error: plugin already installed\n\n";
269                                         exit (3);
270                                 }
272                                 /* Check if dependencies are fullfilled */
273                                 foreach ($depends as $dep){
274                                         if (!in_array($dep, $provides)){
275                                                 echo "! Error: plugin depends on '$dep', but this is not installed\n\n";
276                                                 exit (3);
277                                         }
278                                 }
280                                 /* Create plugstate directory and touch plugin.lst */
281                                 if (!mkdir (PLUGSTATE_DIR."/$name", 0755, TRUE)){
282                                         echo "Failed to create '".PLUGSTATE_DIR."/$name - aborted";
283                                         exit (3);
284                                 }
285                                 if (!$handle= fopen(PLUGSTATE_DIR."/$name/plugin.lst", 'w')) {
286                                         echo "Cannot open file '$filename' - aborted\n";
287                                         exit (1);
288                                 }
290                                 /* Copy and fill plugin.lst */
291                                 $path= dirname($file);
292                                 $dir= new RecursiveDirectoryIterator($path);
293                                 $all= new RecursiveIteratorIterator($dir);
294                                 foreach ( $all as $entry ){
295                                         $source= $path."/".substr($entry->getPathName(), strlen($path) + 1);
297                                         /* Skip well known directories */
298                                         if (preg_match('/^\.+$/', $source) || preg_match('/\/\.svn\//', $source)) {
299                                                 continue;
300                                         }
302                                         /* Calculate destination */
303                                         if (preg_match("%^.*locale/%", $source)){
304                                                 $dest= GOSA_HOME."/locale/plugin/$name/".preg_replace("%^.*locale/%", "", $source);
305                                         } else {
306                                                 $dest= GOSA_HOME."/plugins/".substr($entry->getPathName(), strlen($path) + 1);
307                                         }
309                                         /* Destination exists in case of directories? */
310                                         if ($entry->isDir()){
311                                                 if (!is_dir($dest)){
312                                                         mkdir($dest, 0755, TRUE);
313                                                         fwrite ($handle, "$dest");
314                                                 }
315                                         } else {
316                                                 if (!is_dir(dirname($dest))){
317                                                         mkdir(dirname($dest), 0755, TRUE);
318                                                         fwrite ($handle, "$dest");
319                                                 }
320                                         }
322                                         /* Copy files */
323                                         if ($entry->isFile()){
324                                                 copy ($source, $dest);
325                                                 fwrite ($handle, "$dest");
326                                         }
328                                 }
330                                 fclose($handle);
331                         }
332                 }
333         }
334         
335         /* Update caches */
336         rescan_classes();
337         rescan_i18n();
341 /* Fill global values */
342 $description= $provides= $depends= array();
344 /* Action specified? */
345 if ($argc < 2){
346         rescan_classes();
347         rescan_i18n();
348         exit (0);
351 switch ($argv[1]){
352         case 'install':
353                 if (isset($argv[2])){
354                         install_plugin($argv[2]);
355                 } else {
356                         echo "Usage: update-gosa install-plugin dsc-file\n\n";
357                         exit (1);
358                 }
359                 break;
360         case 'list':
361                 list_plugins();
362                 break;
363         case 'remove':
364                 echo "remove\n";
365                 break;
366         case 'rescan-i18n':
367                 rescan_i18n();
368                 break;
369         case 'rescan-classes':
370                 rescan_classes();
371                 break;
372         default:
373                 echo "Error: Supplied command not known\n\n";
374                 print_usage();
375                 break;
379 ?>