cleanup remove tabs
[tine20] / tine20 / build.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!-- ============================================  -->
4 <!-- Build Definition for Tine 2.0                 -->
5 <!--                                               -->
6 <!-- http://www.tine20.org                         -->
7 <!-- http://www.phing.info                         -->
8 <!-- ============================================  -->
9 <project name="tine20" description="Tine 2.0 build file" default="build">
10
11     <property name="builddir" value="${project.basedir}/build" override="true" />
12     <property name="localedir" value="Tinebase/js/Locale" override="true" />
13
14     <!-- ============================================  -->
15     <!-- Target: prepare                               -->
16     <!-- ============================================  -->
17     <target name="prepare">
18         <echo msg="$buildDate: ${project.basedir}" />
19         <init />
20
21         <php expression="getDevelopmentRevision();" returnProperty="buildRevision" />
22         <echo msg="$buildRevision: ${buildRevision}" />
23
24         <php expression="date_create('now')->format('Y-m-d H:i:s');" returnProperty="buildDate" />
25         <echo msg="$buildDate: ${buildDate}" />
26
27         <echo msg="Making build directory" />
28         <mkdir dir="${builddir}" />
29         <mkdir dir="${builddir}/${localedir}/build" />
30         <mkdir dir="${builddir}/${localedir}/static" />
31     </target>
32
33     <!-- ============================================  -->
34     <!-- Target: build                                 -->
35     <!-- ============================================  -->
36     <target name="build" depends="prepare">
37         <foreach param="name" absparam="path" target="build-module">
38             <fileset dir=".">
39                 <type type="dir" />
40                 <include name="*" />
41                 <exclude name="/" />
42                 <exclude name="*.*" />
43                 <exclude name=".tx" />
44                 <exclude name="build" />
45                 <exclude name="docs" />
46                 <exclude name="fonts" />
47                 <exclude name="images" />
48                 <exclude name="library" />
49                 <exclude name="styles" />
50                 <exclude name="themes" />
51                 <exclude name="vendor" />
52                 <exclude name="Tool" />
53                 <exclude name="Zend" />
54             </fileset>
55         </foreach>
56     </target>
57
58     <!-- ============================================  -->
59     <!-- Target: phpdoc                                -->
60     <!-- ============================================  -->
61     <target name="phpdoc">
62         <echo msg="Building Tine 2.0 PHP API Documentation..." />
63
64         <includepath classpath="${project.basedir}/vendor/phpdocumentor" />
65
66         <mkdir dir="${builddir}/apidocs" />
67
68         <phpdoc2 title="Tine 2.0 PHP API Documentation" destdir="${builddir}/apidocs" template="responsive-twig">
69             <fileset dir=".">
70                 <include name="**/*.php" />
71                 <exclude name="Zend/**.php" />
72                 <exclude name="library/**.php" />
73                 <exclude name="vendor/**.php" />
74             </fileset>
75         </phpdoc2>
76     </target>
77
78     <!-- ============================================  -->
79     <!-- Target: phpunit                               -->
80     <!-- ============================================  -->
81     <target name="phpunit">
82         <echo msg="Starting Tests..." />
83
84         <if>
85             <isset property="configPath" />
86             <then>
87                 <includepath classpath = "${configPath}" />
88             </then>
89         </if>
90
91         <delete dir="${builddir}/reports"/>
92         <mkdir dir="${builddir}/reports" />
93
94         <phpunit configuration="../tests/tine20/phpunit.xml" haltonfailure="true" haltonerror="true" printsummary="true">
95             <formatter type="plain" usefile="false"/>
96             <formatter type="xml" todir="${builddir}/reports"/>
97             <batchtest>
98                 <fileset dir="../tests/tine20">
99                   <include name="**/*Test.php"/>
100                   <exclude name="Tinebase/AccountTest.php"/>
101                 </fileset>
102             </batchtest>
103         </phpunit>
104
105         <phpunitreport infile="${builddir}/reports/testsuites.xml" format="frames" todir="${builddir}/reports/tests"/>
106     </target>
107
108     <!-- ============================================  -->
109     <!-- Target: report                                -->
110     <!-- ============================================  -->
111     <target name="report">
112         <echo msg="Starting Tests..." />
113
114         <delete dir="${builddir}/reports"/>
115         <mkdir dir="${builddir}/reports/tests"/>
116         <mkdir dir="${builddir}/reports/coverage"/>
117         <coverage-setup database="${builddir}/reports/coverage.db">
118             <fileset dir=".">
119                 <include name="**/*.php" />
120                 <exclude name="Zend/**.php" />
121                 <exclude name="library/**.php" />
122                 <exclude name="vendor/**.php" />
123             </fileset>
124         </coverage-setup>
125         <phpunit configuration="../tests/tine20/phpunit.xml" haltonfailure="true" haltonerror="true" printsummary="true" codecoverage="true">
126             <formatter type="xml" todir="${builddir}/reports"/>
127             <batchtest>
128                 <fileset dir="../tests/tine20">
129                   <include name="**/*Test.php"/>
130                   <exclude name="Tinebase/AccountTest.php"/>
131                 </fileset>
132             </batchtest>
133         </phpunit>
134         <phpunitreport infile="${builddir}/reports/testsuites.xml" format="frames" todir="${builddir}/reports/tests"/>
135         <coverage-report outfile="${builddir}/reports/coverage.xml">
136             <report todir="${builddir}/reports/coverage" title="Tine 2.0"/>
137         </coverage-report>
138     </target>
139
140     <!-- ============================================  -->
141     <!-- Target: build-module                          -->
142     <!-- ============================================  -->
143     <target name="build-module" description="build single module" depends="prepare">
144         <echo msg="Building ${name}" />
145
146         <!-- do jsb2tk build -->
147         <jsb2tk-build appName="${name}" />
148
149         <!-- replace buildstuff -->
150         <reflexive>
151             <filterchain>
152                 <replaceregexp>
153                     <regexp pattern="Tine\.clientVersion\.buildType\s*=[^=]{1}[^;]*" replace='Tine.clientVersion.buildType="RELEASE"' modifiers="i" />
154                     <regexp pattern="Tine\.clientVersion\.buildDate\s*=[^=]{1}[^;]*" replace='Tine.clientVersion.buildDate="${buildDate}"' modifiers="i"/>
155                     <regexp pattern="Tine\.clientVersion\.buildRevision\s*=[^=]{1}[^;]*" replace='Tine.clientVersion.codeName="${buildRevision}"' modifiers="i"/>
156                 </replaceregexp>
157             </filterchain>
158
159             <fileset dir="${builddir}">
160                 <include name="${name}/js/*-FAT*" />
161             </fileset>
162         </reflexive>
163
164         <!-- debug mode for debug files -->
165         <reflexive>
166             <filterchain>
167                 <replaceregexp>
168                     <regexp pattern="Tine\.clientVersion\.buildType\s*=[^=]{1}[^;]*" replace="Tine.clientVersion.buildType = 'DEBUG'"/>
169                 </replaceregexp>
170             </filterchain>
171
172             <fileset dir="${builddir}">
173                 <include name="${name}/js/*-FAT-debug*" />
174             </fileset>
175         </reflexive>
176
177         <!-- original jsb2 builds -->
178         <!-- NOTE as jsb2tk has no path adoption yet we need to do it here -->
179         <copy toDir="${project.basedir}">
180             <fileset dir="${builddir}">
181                 <include name="${name}/*/*" />
182             </fileset>
183
184             <filterchain>
185                 <replaceregexp>
186                     <regexp pattern="(\.\.\/){2,}images" replace="../../images" modifiers="i"/>
187                     <regexp pattern="(\.\.\/){2,}library" replace="../../library" modifiers="i"/>
188                 </replaceregexp>
189             </filterchain>
190
191         </copy>
192
193         <!-- adopt path for getJS/getCSS -->
194         <!-- TODO add deploymode GETTER and move this to jsb2tk -->
195         <copy toDir="${project.basedir}">
196             <mapper type="regexp" from="^(.*\.(js|css))" to="\1.inc"/>
197
198             <filterchain>
199                 <replaceregexp>
200                     <regexp pattern="(\.\.\/)+images" replace="images" modifiers="i"/>
201                     <regexp pattern="(\.\.\/)+library" replace="library" modifiers="i"/>
202                 </replaceregexp>
203             </filterchain>
204
205             <fileset dir="${builddir}">
206                 <include name="${name}/*/*" />
207             </fileset>
208
209         </copy>
210
211         <!-- translations -->
212         <translation-build appName="${name}" />
213         <jsMin targetDir="${builddir}/${name}/js" failOnError="false">
214             <fileset dir="${builddir}/${name}/js">
215                 <include name="*-lang-*-debug.js"/>
216             </fileset>
217         </jsMin>
218
219         <copy toDir="${project.basedir}/${name}/js">
220             <fileset dir="${builddir}/${name}/js">
221                 <include name="*-lang-*-debug.js" />
222             </fileset>
223         </copy>
224
225         <copy toDir="${project.basedir}/${name}/js">
226             <fileset dir="${builddir}/${name}/js">
227                 <include name="*-lang-*-debug-min.js" />
228             </fileset>
229
230             <mapper type="regexp" from="^(.*)-debug-min.js" to="\1.js"/>
231         </copy>
232
233     </target>
234
235     <!-- ============================================  -->
236     <!-- Target: clean                                 -->
237     <!-- ============================================  -->
238     <target name="clean">
239         <delete dir="${builddir}" includeemptydirs="true" verbose="false" failonerror="false" />
240         <delete>
241             <fileset dir=".">
242                 <include name="*/*/*-FAT*" />
243                 <include name="*/js/*-lang-*" />
244                 <include name="${project.basedir}/${localedir}/build/*" />
245             </fileset>
246         </delete>
247     </target>
248
249     <!-- ============================================  -->
250     <!-- Target: mimetypes                                 -->
251     <!-- ============================================  -->
252     <target name="mimetypes">
253         <build-mimetypes appName="${name}" />
254     </target>
255
256     <!-- ============================================  -->
257     <!-- Target: tx-pull                               -->
258     <!-- ============================================  -->
259     <target name="tx-pull">
260         <echo msg="pull translations from transifex" />
261         <exec command="tx pull -a -f --skip" passthru="true" />
262         <echo msg="commit updated strings now:" />
263         <echo msg="git add */translations" />
264         <echo msg="git commit -m '#7086: update translation files'" />
265         <echo msg="git push gerrit HEAD:refs/heads/master" />
266     </target>
267
268     <!-- ============================================  -->
269     <!-- Target: tx-push                               -->
270     <!-- ============================================  -->
271     <target name="tx-push">
272         <echo msg="updating templates" />
273         <exec command="./langHelper.php --pot" passthru="true" />
274         <echo msg="push translations to transifex" />
275         <exec command="tx push -s" passthru="true" />
276         <echo msg="commit updated strings now:" />
277         <echo msg="git commit -a -m 'update lang templates'" />
278         <echo msg="git push gerrit HEAD:refs/heads/master" />
279     </target>
280
281     <!-- ============================================  -->
282     <!-- Task: init                                    -->
283     <!-- ============================================  -->
284     <adhoc-task name="init"><![CDATA[
285         class initTask extends Task {
286             function main() {
287                 echo `composer install`;
288                 require_once 'vendor/autoload.php';
289             }
290         }
291     ]]></adhoc-task>
292
293     <!-- ============================================  -->
294     <!-- Task: jsb2tk-build                            -->
295     <!-- ============================================  -->
296     <adhoc-task name="jsb2tk-build"><![CDATA[
297         class jsb2tkTask extends Task {
298             private $appName;
299
300             function setAppName($appName) {
301                 $this->appName = $appName;
302             }
303
304             function main() {
305                 $jsb2 = "${project.basedir}/{$this->appName}/{$this->appName}.jsb2";
306                 if (file_exists($jsb2)) {
307                     $this->log("In jsb2tkTask: " . $this->appName);
308
309                     require_once('${project.basedir}/library/jsb2tk/jsb2tk.php');
310
311                     $tk = new jsb2tk(array(
312                         'homeDir' => '${builddir}'
313                     ));
314
315                     $tk->register($jsb2);
316                     $tk->buildAll();
317                 }
318             }
319         }
320     ]]></adhoc-task>
321
322     <!-- ============================================  -->
323     <!-- Task: translation-build                       -->
324     <!-- ============================================  -->
325     <adhoc-task name="translation-build"><![CDATA[
326         class translationTask extends Task {
327             private $appName;
328
329             function setAppName($appName) {
330                 $this->appName = $appName;
331             }
332
333             function main() {
334                 if (! file_exists('${builddir}/' . "{$this->appName}/js")) return;
335                 $availableTranslations = Tinebase_Translation::getAvailableTranslations();
336
337                 foreach ($availableTranslations as $translation) {
338                     $localeString = $translation['locale'];
339                     $locale = new Zend_Locale($localeString);
340
341                     $jsTranslation = Tinebase_Translation::getJsTranslations($locale, $this->appName);
342
343                     if ($this->appName == 'Tinebase' && file_exists('${project.basedir}/langstatistics.json')) {
344                         $langstatistics = json_decode(file_get_contents('${project.basedir}/langstatistics.json'), TRUE);
345                         $localeStats = array_values(array_filter($langstatistics['langStats'], function($stats) use ($localeString) {return $stats['locale'] == $localeString;}));
346                         $jsTranslation .= ("Locale.translationStats=" . json_encode($localeStats[0]) . ";\n");
347                     }
348
349                     file_put_contents('${builddir}/' . "{$this->appName}/js/{$this->appName}-lang-{$locale}-debug.js", $jsTranslation);
350                 }
351
352                 foreach (Tinebase_Translation::getTranslationDirs() as $appName => $translationPath) {
353                     foreach (scandir($translationPath) as $poFile) {
354                         if (substr($poFile, -3) == '.po') {
355                             $langName = substr($poFile, 0, -3);
356                             `cd "$translationPath"
357                             msgfmt -o $langName.mo $poFile`;
358                         }
359                     }
360                 }
361             }
362         }
363     ]]></adhoc-task>
364
365     <!-- ============================================  -->
366     <!-- Task: build-mimetypes                         -->
367     <!-- ============================================  -->
368     <adhoc-task name="build-mimetypes"><![CDATA[
369         class mimetypeTask extends Task {
370             private $appName;
371
372             function setAppName($appName) {
373                 $this->appName = $appName;
374             }
375
376             function buildMimeTypesStyleFile($resolution, &$styleSheet) {
377
378                 $relatedImgPath = '/images/oxygen/'.$resolution.'/mimetypes/';
379                 $imgPath = '${project.basedir}'.$relatedImgPath;
380                 if (! file_exists($imgPath) || ! is_dir($imgPath)) {
381                     echo 'Mimetype images no found!';
382                     return;
383                 }
384
385                 // √∂ffnen des Verzeichnisses
386                 if ( $handle = opendir($imgPath) ) {
387
388                     fwrite($styleSheet, ".standardFileClass_".$resolution." .x-grid3-cell-inner {\n");
389                     fwrite($styleSheet, "    background-image: url(../..".$relatedImgPath."application-octet-stream.png);\n");
390                     fwrite($styleSheet, "    background-repeat:  no-repeat;\n");
391                     fwrite($styleSheet, "    padding-left: 19px;\n");
392                     fwrite($styleSheet, "}\n\n");
393
394                     // einlesen der Verzeichnisses
395                     while (($file = readdir($handle)) !== false)
396                     {
397                         $fileName = basename($file, '.png');
398
399                         $addToStyle = strcmp($fileName, "..") + strcmp($fileName, "..");
400                         if($addToStyle > 0) {
401
402                             fwrite($styleSheet, ".".$fileName."_".$resolution." .x-grid3-cell-inner {\n");
403                             fwrite($styleSheet, "    background-image: url(../..".$relatedImgPath.$file.") !important;\n");
404                             fwrite($styleSheet, "    background-repeat:  no-repeat;\n");
405                             fwrite($styleSheet, "    padding-left: 19px;\n");
406                             fwrite($styleSheet, "}\n\n");
407                         }
408                     }
409
410                     closedir($handle);
411                 }
412
413             }
414
415             function main() {
416                     $styleSheet = fopen('Tinebase/css/mimetypes.css', 'w+');
417                     $this->buildMimeTypesStyleFile('16x16', $styleSheet);
418                     $this->buildMimeTypesStyleFile('22x22', $styleSheet);
419                     $this->buildMimeTypesStyleFile('32x32', $styleSheet);
420                     fclose($styleSheet);
421             }
422         }
423     ]]></adhoc-task>
424
425
426     <!-- ============================================  -->
427     <!-- Task: manifest-build                          -->
428     <!-- TODO  make it working (just a codestore)      -->
429     <!-- ============================================  -->
430     <adhoc-task name="manifest-build"><![CDATA[
431         class manifestBuildTask extends Task {
432             private $appName;
433
434             function setAppName($appName) {
435                 $this->appName = $appName;
436             }
437
438             function main() {
439                 $defaultFiles = "CACHE MANIFEST\n# Build by $build\nCACHE:\n";
440
441                 $manifest = fopen('${project.basedir}/tine20.manifest', 'w+');
442                 fwrite($manifest, $defaultFiles . "\n");
443
444                 $files = array(
445                     'Tinebase/css/tine-all.css',
446                     'Tinebase/js/tine-all.js',
447                     'styles/tine20.css', 
448                     'library/ExtJS/ext-all.js',
449                     'library/ExtJS/adapter/ext/ext-base.js',
450                     'library/ExtJS/resources/css/ext-all.css',
451                     'images/oxygen/16x16/actions/knewstuff.png' // ???
452                 );
453
454                 // no subdirs! => solaris does not know find -maxdeps 1
455                 exec("cd \"$tine20path\"; ls images/* | grep images/ | egrep '\.png|\.gif|\.jpg'", $baseImages);
456                 $files = array_merge($files, $baseImages);
457
458                 $tineCSS = file_get_contents($tine20path . '/Tinebase/css/tine-all-debug.css');
459                 preg_match_all('/url\(..\/..\/(images.*)\)/U', $tineCSS, $matches);
460                 $files = array_merge($files, $matches[1]);
461
462                 $tineCSS = file_get_contents($tine20path . '/Tinebase/css/tine-all-debug.css');
463                 preg_match_all('/url\(..\/..\/(library.*)\)/U', $tineCSS, $matches);
464                 $files = array_merge($files, $matches[1]);
465
466                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
467                 preg_match_all('/labelIcon: [\'|"](.*png)/U', $tineJs, $matches);
468                 $files = array_merge($files, $matches[1]);
469
470                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
471                 preg_match_all('/labelIcon: [\'|"](.*gif)/U', $tineJs, $matches);
472                 $files = array_merge($files, $matches[1]);
473
474                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
475                 preg_match_all('/src=[\'|"](.*png)/U', $tineJs, $matches);
476                 $files = array_merge($files, $matches[1]);
477
478                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
479                 preg_match_all('/src=[\'|"](.*gif)/U', $tineJs, $matches);
480                 $files = array_merge($files, $matches[1]);
481
482                 exec("cd \"$tine20path\"; find library/ExtJS/resources/images -type f -name *.gif", $extImages);
483                 $files = array_merge($files, $extImages);
484                 exec("cd \"$tine20path\"; find library/ExtJS/resources/images -type f -name *.png", $extImages);
485                 $files = array_merge($files, $extImages);
486
487                 exec("cd \"$tine20path\"; find styles -type f", $tine20Styles);
488                 $files = array_merge($files, $tine20Styles);
489
490                 $files = array_unique($files);
491
492                 foreach($files as $file) {
493                     if (! is_file("$tine20path/$file")) {
494                         echo "WARNING $file not found, removing it from manifest.\n";
495                     } else if (substr(basename($file), 0, 1) == '.' || ! preg_match('/(js|css|gif|png|jpg)$/', $file))  {
496                         echo "INFO $file is unwanted, removing it from manifest.\n";
497                     } else {
498                         fwrite($manifest, $file . "\n");
499                     }
500                 }
501
502                 fclose($manifest);
503             }
504         }
505     ]]></adhoc-task>
506
507     <!-- ============================================  -->
508     <!-- Task: zend-translation-build                  -->
509     <!-- TODO  make a target for this                  -->
510     <!-- ============================================  -->
511     <adhoc-task name="zend-translation-build"><![CDATA[
512         class zendTranslationTask extends Task {
513             function main() {
514                 // dump one langfile for every locale
515                 $localelist = Zend_Locale::getLocaleList();
516                 foreach ($localelist as $locale => $something) {
517                     try {
518                         $js = $this->createJsTranslationLists($locale);
519                         file_put_contents('${builddir}/${localedir}/static/' . "generic-$locale-debug.js", $js);
520                     } catch (Exception $e) {
521                         echo "WARNING: could not create translation file for '$locale': '{$e->getMessage()}'\n";
522                     }
523                 }
524             }
525
526             /**
527              * creates translation lists js files for locale with js object
528              *
529              * @param   string $_locale
530              * @return  string the file contents
531              */
532             function createJsTranslationLists($_locale) {
533                 $jsContent = "Locale.prototype.TranslationLists = {\n";
534
535                 $types = array(
536                     'Date'           => array('path' => 'Date'),
537                     'Time'           => array('path' => 'Time'),
538                     'DateTime'       => array('path' => 'DateTime'),
539                     'Month'          => array('path' => 'Month'),
540                     'Day'            => array('path' => 'Day'),
541                     'Symbols'        => array('path' => 'Symbols'),
542                     'Question'       => array('path' => 'Question'),
543                     'Language'       => array('path' => 'Language'),
544                     'CountryList'    => array('path' => 'Territory', 'value' => 2),
545                     'Territory'      => array('path' => 'Territory', 'value' => 1),
546                     'CityToTimezone' => array('path' => 'CityToTimezone'),
547                 );
548
549                 $zendLocale = new Zend_Locale($_locale);
550
551                 foreach ( $types as $name => $path) {
552                     $list = $zendLocale->getTranslationList($path['path'], $_locale, array_key_exists('value', $path) ? $path['value'] : false);
553                     //print_r ( $list );
554
555                     if ( is_array($list) ) {
556                         $jsContent .= "\n\t$name: {";
557
558                         foreach ( $list as $key => $value ) {
559                             // convert ISO -> PHP for date formats
560                             if ( in_array($name, array('Date', 'Time', 'DateTime')) ) {
561                                 $value = $this->convertIsoToPhpFormat($value);
562                             }
563                             $value = preg_replace("/\"/", '\"', $value);
564                             $jsContent .= "\n\t\t'$key': \"$value\",";
565                         }
566                         // remove last comma
567                         $jsContent = chop($jsContent, ",");
568
569                         $jsContent .= "\n\t},";
570                     }
571                 }
572                 $jsContent = chop($jsContent, ",");
573
574                 $jsContent .= "\n};\n";
575                 return $jsContent;
576             }
577
578             /**
579              * Converts a format string from ISO to PHP format
580              * reverse the functionality of Zend's convertPhpToIsoFormat()
581              *
582              * @param  string  $format  Format string in PHP's date format
583              * @return string           Format string in ISO format
584              */
585             function convertIsoToPhpFormat($format) {
586                 $convert = array(
587                     'c' => '/yyyy-MM-ddTHH:mm:ssZZZZ/',
588                     '$1j$2' => '/([^d])d([^d])/',
589                     'j$1' => '/^d([^d])/',
590                     '$1j' => '/([^d])d$/',
591                     't' => '/ddd/',
592                     'd' => '/dd/',
593                     'l' => '/EEEE/',
594                     'D' => '/EEE/',
595                     'S' => '/SS/',
596                     'w' => '/eee/',
597                     'N' => '/e/',
598                     'z' => '/D/',
599                     'W' => '/w/',
600                     '$1n$2' => '/([^M])M([^M])/',
601                     'n$1' => '/^M([^M])/',
602                     '$1n' => '/([^M])M$/',
603                     'F' => '/MMMM/',
604                     'M' => '/MMM/',
605                     'm' => '/MM/',
606                     'L' => '/l/',
607                     'o' => '/YYYY/',
608                     'Y' => '/yyyy/',
609                     'y' => '/yy/',
610                     'a' => '/a/',
611                     'A' => '/a/',
612                     'B' => '/B/',
613                     'h' => '/hh/',
614                     'g' => '/h/',
615                     '$1G$2' => '/([^H])H([^H])/',
616                     'G$1' => '/^H([^H])/',
617                     '$1G' => '/([^H])H$/',
618                     'H' => '/HH/',
619                     'i' => '/mm/',
620                     's' => '/ss/',
621                     'e' => '/zzzz/',
622                     'I' => '/I/',
623                     'P' => '/ZZZZ/',
624                     'O' => '/Z/',
625                     'T' => '/z/',
626                     'Z' => '/X/',
627                     'r' => '/r/',
628                     'U' => '/U/',
629                 );
630
631                 //echo "pre:".$format."\n";
632
633                 $patterns = array_values($convert);
634                 $replacements = array_keys($convert);
635                 $format = preg_replace($patterns, $replacements, $format);
636
637                 //echo "post:".$format."\n";
638                 //echo "---\n";
639
640                 return $format;
641             }
642         }
643     ]]></adhoc-task>
644 </project>