Code

e94948b24d3d06bc38a2775f586e04eb44ca4681
[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, $versions, $conflicts;
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                                 $versions[$res]= $plugin['version'];
171                                 if (isset($plugin['depends'])){
172                                         $depends[$res]= explode(',', preg_replace('/\s+/', '', $plugin['depends']));
173                                 }
174                                 if (isset($plugin['conflicts'])){
175                                         $conflicts[$res]= explode(',', preg_replace('/\s+/', '', $plugin['conflicts']));
176                                 }
177                         }
178                 }
179         }
181         return $res;
185 function dependency_check()
187         global $description, $provides, $depends;
189         foreach ($depends as $name => $pl_depends){
190                 foreach ($pl_depends as $pl){
191                         if (!in_array($pl, $provides)){
192                                 echo "! Error: plugin '$name' depends on '$pl' which is not provided by any plugin\n\n";
193                                 exit (1);
194                         }
195                 }
196         }
200 function load_plugins()
202         if (!is_dir(PLUGSTATE_DIR)){
203                 if (!mkdir (PLUGSTATE_DIR, 0755, TRUE)){
204                         echo "Cannot create plugstate dir '".PLUGSTATE_DIR."' - aborted\n";
205                         exit (2);
206                 }
207         }
208         $dir= new DirectoryIterator(PLUGSTATE_DIR);
209         foreach ($dir as $entry){
210                 if ($dir->isDir() && !preg_match('/^\./', $dir->__toString())){
211                         $file= $dir->getPathName()."/plugin.dsc";
212                         if (parse_ini($file) == ""){
213                                 echo "! Warning: plugin ".$dir->getPathName()." is missing declarations\n";
214                         }
215                 }
216         }
220 function list_plugins()
222         global $description, $versions;
223         $count= 0;
225         /* Load plugin list */
226         load_plugins();
228         /* Show plugins */
229         foreach ($description as $name => $dsc){
230                 if ($count == 0){
231                         echo "Plugin\t\t|Version |Description\n";
232                         echo "----------------------------------------------------------------------------\n";
233                 }
234                 $ver= $versions[$name];
235                 echo "$name\t\t|$ver\t |$dsc\n";
236                 $count++;
237         }
239         /* Yell about non existing plugins... */
240         if ($count == 0){
241                 echo "No plugins found...\n\n";
242         } else {
243                 # Check for dependencies
244                 dependency_check();
245                 echo "\n";
246         }
250 function install_plugin($file)
252         global $description, $provides, $depends, $conflicts;
254         /* Load plugin list */
255         load_plugins();
257         /* Load .dsc file */
258         if (file_exists($file)){
259                 $tmp= parse_ini_file($file, TRUE);
261                 if (isset($tmp['gosa-plugin'])){
262                         $plugin= &$tmp['gosa-plugin'];
263                         if (isset($plugin['name'])&& isset($plugin['description'])){
264                                 $name= $plugin['name'];
265                                 $description= $plugin['description'];
266                                 $depends= array();
267                                 if (isset($plugin['depends'])){
268                                         $depends= explode(',', preg_replace('/\s+/', '', $plugin['depends']));
269                                 }
271                                 /* Already installed? */
272                                 if (isset($provides[$name])){
273                                         echo "! Error: plugin already installed\n\n";
274                                         exit (3);
275                                 }
277                                 /* Check if dependencies are fullfilled */
278                                 foreach ($depends as $dep){
279                                         if (!in_array($dep, $provides)){
280                                                 echo "! Error: plugin depends on '$dep', but this is not installed\n\n";
281                                                 exit (3);
282                                         }
283                                 }
285                                 /* Check for conflicts */
286                                 foreach ($conflicts as $conf){
287                                         if (!in_array($conf, $provides)){
288                                                 echo "! Warning: plugin conflicts with '$conf'\n\n";
289                                         }
290                                 }
292                                 /* Create plugstate directory and touch plugin.lst */
293                                 if (!mkdir (PLUGSTATE_DIR."/$name", 0755, TRUE)){
294                                         echo "Failed to create '".PLUGSTATE_DIR."/$name - aborted";
295                                         exit (3);
296                                 }
297                                 if (!$handle= fopen(PLUGSTATE_DIR."/$name/plugin.lst", 'w')) {
298                                         echo "Cannot open file '$filename' - aborted\n";
299                                         exit (1);
300                                 }
302                                 /* Copy and fill plugin.lst */
303                                 $path= dirname($file);
304                                 $dir= new RecursiveDirectoryIterator($path);
305                                 $all= new RecursiveIteratorIterator($dir);
306                                 foreach ( $all as $entry ){
307                                         $source= $path."/".substr($entry->getPathName(), strlen($path) + 1);
309                                         /* Skip description - it belongs to the state dir */
310                                         if (preg_match('/\/plugin.dsc$/', $source)){
311                                                 copy ($source, PLUGSTATE_DIR."/$name/plugin.dsc");
312                                                 continue;
313                                         }
315                                         /* Skip well known directories */
316                                         if (preg_match('/^\.+$/', $source) || preg_match('/\/\.svn\//', $source)) {
317                                                 continue;
318                                         }
320                                         /* Calculate destination */
321                                         if (preg_match("%^.*locale/%", $source)){
322                                                 $dest= GOSA_HOME."/locale/plugin/$name/".preg_replace("%^.*locale/%", "", $source);
323                                         } else {
324                                                 $dest= GOSA_HOME."/plugins/".substr($entry->getPathName(), strlen($path) + 1);
325                                         }
327                                         /* Destination exists in case of directories? */
328                                         if ($entry->isDir()){
329                                                 if (!is_dir($dest)){
330                                                         mkdir($dest, 0755, TRUE);
331                                                         fwrite ($handle, "$dest");
332                                                 }
333                                         } else {
334                                                 if (!is_dir(dirname($dest))){
335                                                         mkdir(dirname($dest), 0755, TRUE);
336                                                         fwrite ($handle, "$dest");
337                                                 }
338                                         }
340                                         /* Copy files */
341                                         if ($entry->isFile()){
342                                                 copy ($source, $dest);
343                                                 fwrite ($handle, "$dest");
344                                         }
346                                 }
348                                 fclose($handle);
349                         }
350                 }
351         }
352         
353         /* Update caches */
354         rescan_classes();
355         rescan_i18n();
359 /* Fill global values */
360 $description= $provides= $depends= $versions= $conflicts= array();
362 /* Action specified? */
363 if ($argc < 2){
364         rescan_classes();
365         rescan_i18n();
366         exit (0);
369 switch ($argv[1]){
370         case 'install':
371                 if (isset($argv[2])){
372                         install_plugin($argv[2]);
373                 } else {
374                         echo "Usage: update-gosa install-plugin dsc-file\n\n";
375                         exit (1);
376                 }
377                 break;
378         case 'list':
379                 list_plugins();
380                 break;
381         case 'remove':
382                 echo "remove\n";
383                 break;
384         case 'rescan-i18n':
385                 rescan_i18n();
386                 break;
387         case 'rescan-classes':
388                 rescan_classes();
389                 break;
390         default:
391                 echo "Error: Supplied command not known\n\n";
392                 print_usage();
393                 break;
397 ?>