Merge branch '2015.11-develop' into 2016.03
[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="userdatadir" value="${project.basedir}/userdata" override="true" />
13     <property name="localedir" value="Tinebase/js/Locale" override="true" />
14     <property name="configdir" value="${project.basedir}" override="true" />
15     <property name="testconfigdir" value="${project.basedir}/../tests/tine20" override="true" />
16     
17     <!-- ============================================  -->
18     <!-- Target: prepare                               -->
19     <!-- ============================================  -->
20     <target name="prepare">
21         <echo msg="basedir: ${project.basedir}" />
22         <init />
23
24         <php expression="Tinebase_Helper::getDevelopmentRevision();" returnProperty="buildRevision" />
25         <echo msg="$buildRevision: ${buildRevision}" />
26
27         <php expression="date_create('now')->format('Y-m-d H:i:s');" returnProperty="buildDate" />
28         <echo msg="$buildDate: ${buildDate}" />
29
30         <echo msg="Making build directory" />
31         <mkdir dir="${builddir}" />
32         <mkdir dir="${builddir}/${localedir}/build" />
33         <mkdir dir="${builddir}/${localedir}/static" />
34     </target>
35
36     <!-- ============================================  -->
37     <!-- Target: build                                 -->
38     <!-- ============================================  -->
39     <target name="build" depends="prepare">
40         <foreach param="name" absparam="path" target="prepared-build-module">
41             <fileset dir=".">
42                 <type type="dir" />
43                 <include name="*" />
44                 <exclude name="/" />
45                 <exclude name="*.*" />
46                 <exclude name=".tx" />
47                 <exclude name="build" />
48                 <exclude name="docs" />
49                 <exclude name="fonts" />
50                 <exclude name="images" />
51                 <exclude name="library" />
52                 <exclude name="styles" />
53                 <exclude name="themes" />
54                 <exclude name="vendor" />
55                 <exclude name="userdata" />
56                 <exclude name="Tool" />
57                 <exclude name="Zend" />
58             </fileset>
59         </foreach>
60     </target>
61
62     <!-- ============================================  -->
63     <!-- Target: phpdoc                                -->
64     <!-- ============================================  -->
65     <target name="phpdoc">
66         <echo msg="Building Tine 2.0 PHP API Documentation..." />
67
68         <includepath classpath="${project.basedir}/vendor/phpdocumentor" />
69
70         <mkdir dir="${builddir}/apidocs" />
71
72         <phpdoc2 title="Tine 2.0 PHP API Documentation" destdir="${builddir}/apidocs" template="responsive-twig">
73             <fileset dir=".">
74                 <include name="**/*.php" />
75                 <exclude name="Zend/**.php" />
76                 <exclude name="library/**.php" />
77                 <exclude name="vendor/**.php" />
78             </fileset>
79         </phpdoc2>
80     </target>
81     
82     <!-- ============================================                       -->
83     <!-- Target: phpunit                                                    -->
84     <!--                                                                    -->
85     <!-- you can define the includes like this (runs all Tinebase tests):   -->
86     <!-- $ vendor/bin/phing phpunit -Dtestinclude=Tinebase/**/*Test.php     -->
87     <!-- ============================================                       -->
88     <target name="phpunit">
89         <!-- TODO we still have some test files that are named *Tests.php, rename them or adjust the include property -->
90         <property name="testinclude" value="**/*Test.php" override="true" />
91         
92         <echo msg="Starting Tests..." />
93         <echo msg="Using config file ${testconfigdir}/phpunit.xml" />
94         
95         <!-- do we need this? -->
96         <!--includepath classpath = "${testconfigdir}" /-->
97         
98         <delete dir="${builddir}/reports" />
99         <mkdir dir="${builddir}/reports" />
100         <mkdir dir="${builddir}/reports/tests" />
101         
102         <phpunit configuration="${testconfigdir}/phpunit.xml" haltonfailure="true" printsummary="true">
103             <formatter type="plain" usefile="false" />
104             <formatter type="xml" todir="${builddir}/reports" />
105             <batchtest>
106                 <fileset dir="${project.basedir}/../tests/tine20">
107                   <include name="${testinclude}" />
108                   <exclude name="Tinebase/AccountTest.php" />
109                 </fileset>
110             </batchtest>
111         </phpunit>
112         
113         <phpunitreport infile="${builddir}/reports/testsuites.xml" format="frames" todir="${builddir}/reports/tests" />
114     </target>
115
116     <!-- ============================================  -->
117     <!-- Target: phpunit-prepare                       -->
118     <!-- ============================================  -->
119     <target name="phpunit-prepare">
120         <echo msg="Preparing for phpunit" />
121
122         <echo msg="Making report directories" />
123         <mkdir dir="${builddir}/reports" />
124
125         <echo msg="Making userdata directories" />
126         <mkdir dir="${userdatadir}/cache"/>
127         <mkdir dir="${userdatadir}/sessions"/>
128         <mkdir dir="${userdatadir}/tmp"/>
129         <mkdir dir="${userdatadir}/files"/>
130         <mkdir dir="${userdatadir}/log"/>
131     </target>
132     
133     <!-- ============================================      -->
134     <!-- Target: phpunit-exec                              -->
135     <!--                                                   -->
136     <!-- this runs phpunit in an exec task. we do this     -->
137     <!-- to overcome some drawbacks (for example we can't  -->
138     <!-- use the LogListener) of the phing phpunit task.   -->
139     <!-- ============================================      -->
140     <target name="phpunit-exec" depends="clean, phpunit-prepare">
141         <property name="testinclude" value="AllTests.php" override="true" />
142         <property name="includepath" value=".:/usr/share/php/:${configdir}:${project.basedir}:${project.basedir}/library:${project.basedir}/vendor/zendframework/zendframework1/library" override="true" />
143         <property name="testadditionalparams" value="" override="true" />
144         <property name="testsuite" value="tine20" override="true" />
145         
146         <echo msg="Starting Tests..." />
147         <echo msg="Using config file ${testconfigdir}/phpunit.xml" />
148         <echo msg="Setting include_path to ${includepath}" />
149         
150         <exec executable="${project.basedir}/vendor/bin/phpunit" dir="${project.basedir}/../tests/${testsuite}" passthru="true">
151              <arg line="-d max_execution_time=0
152              -d include_path=${includepath}
153              --configuration ${testconfigdir}/phpunit.xml
154              --log-junit ${builddir}/reports/junit.xml
155              ${testadditionalparams}
156              ${testinclude} " />
157         </exec>
158     </target>
159
160     <!-- ============================================      -->
161     <!-- Target: phpunit-serv                              -->
162     <!--                                                   -->
163     <!-- this runs phpunit in an exec task. we do this     -->
164     <!-- to overcome some drawbacks (for example we can't  -->
165     <!-- use the LogListener) of the phing phpunit task.   -->
166     <!-- ============================================      -->
167     <target name="phpunit-serv" depends="clean, phpunit-prepare">
168         <property name="testinclude" value="AllServerTests.php" override="true" />
169         <property name="includepath" value=".:/usr/share/php/:${configdir}:${project.basedir}:${project.basedir}/library/:${project.basedir}/vendor/zendframework/zendframework1/library" override="true" />
170         <property name="testadditionalparams" value="" override="true" />
171
172         <echo msg="Starting Server Tests..." />
173         <echo msg="Using config file ${testconfigdir}/phpunit.xml" />
174         <echo msg="Setting include_path to ${includepath}" />
175
176         <exec executable="${project.basedir}/vendor/bin/phpunit" dir="${project.basedir}/../tests/tine20" passthru="true">
177             <arg line="-d max_execution_time=0
178              -d include_path=${includepath}
179              --configuration ${testconfigdir}/phpunit.xml
180              --log-junit ${builddir}/reports/junit.xml
181              ${testadditionalparams}
182              ${testinclude} " />
183         </exec>
184     </target>
185
186     <!-- ============================================  -->
187     <!-- Target: report                                -->
188     <!-- TODO remove code duplication (phpunit target) OR remove this -->
189     <!-- ============================================  -->
190     <target name="report">
191         <echo msg="Starting Tests..." />
192
193         <delete dir="${builddir}/reports"/>
194         <mkdir dir="${builddir}/reports/tests"/>
195         <mkdir dir="${builddir}/reports/coverage"/>
196         <coverage-setup database="${builddir}/reports/coverage.db">
197             <fileset dir=".">
198                 <include name="**/*.php" />
199                 <exclude name="Zend/**.php" />
200                 <exclude name="library/**.php" />
201                 <exclude name="vendor/**.php" />
202             </fileset>
203         </coverage-setup>
204         <phpunit configuration="../tests/tine20/phpunit.xml" haltonfailure="true" haltonerror="true" printsummary="true" codecoverage="true">
205             <formatter type="xml" todir="${builddir}/reports"/>
206             <batchtest>
207                 <fileset dir="../tests/tine20">
208                   <include name="**/*Test.php"/>
209                   <exclude name="Tinebase/AccountTest.php"/>
210                 </fileset>
211             </batchtest>
212         </phpunit>
213         <phpunitreport infile="${builddir}/reports/testsuites.xml" format="frames" todir="${builddir}/reports/tests"/>
214         <coverage-report outfile="${builddir}/reports/coverage.xml">
215             <report todir="${builddir}/reports/coverage" title="Tine 2.0"/>
216         </coverage-report>
217     </target>
218
219     <!-- ============================================  -->
220     <!-- Target: build-module                          -->
221     <!-- ============================================  -->
222     <target name="build-module" description="build single module" depends="prepare">
223         <phingcall target="prepared-build-module">
224             <property name="name" value="${name}" />
225         </phingcall>
226     </target>
227     <target name="prepared-build-module" description="build single module">
228         <echo msg="Building ${name}" />
229
230         <!-- ensure npm -->
231         <if>
232             <available file="${project.basedir}/${name}/js/package.json"/>
233             <then>
234                 <echo message="Starting npm..." />
235                 <exec command="npm install" dir="${project.basedir}/${name}/js" passthru="true" />
236             </then>
237         </if>
238
239         <!-- do webpack build -->
240         <if>
241             <available file="${project.basedir}/${name}/js/webpack.config.js"/>
242             <then>
243                 <echo message="Starting webpack..." />
244                 <exec command="webpack --output-path ${builddir}/${name}/js" dir="${project.basedir}/${name}/js" passthru="true" />
245             </then>
246         </if>
247         <available file="${builddir}/${name}/js/webpack.config.js" property="webpack" value="Yes"/>
248
249
250         <!-- do jsb2tk build -->
251         <jsb2tk-build appName="${name}" />
252
253         <!-- replace buildstuff -->
254         <reflexive>
255             <filterchain>
256                 <replaceregexp>
257                     <regexp pattern="Tine\.clientVersion\.buildType\s*=[^=]{1}[^;]*" replace='Tine.clientVersion.buildType="RELEASE"' modifiers="i" />
258                     <regexp pattern="Tine\.clientVersion\.buildDate\s*=[^=]{1}[^;]*" replace='Tine.clientVersion.buildDate="${buildDate}"' modifiers="i"/>
259                     <regexp pattern="Tine\.clientVersion\.buildRevision\s*=[^=]{1}[^;]*" replace='Tine.clientVersion.codeName="${buildRevision}"' modifiers="i"/>
260                 </replaceregexp>
261             </filterchain>
262
263             <fileset dir="${builddir}">
264                 <include name="${name}/js/*-FAT*" />
265             </fileset>
266         </reflexive>
267
268         <!-- debug mode for debug files -->
269         <reflexive>
270             <filterchain>
271                 <replaceregexp>
272                     <regexp pattern="Tine\.clientVersion\.buildType\s*=[^=]{1}[^;]*" replace="Tine.clientVersion.buildType = 'DEBUG'"/>
273                 </replaceregexp>
274             </filterchain>
275
276             <fileset dir="${builddir}">
277                 <include name="${name}/js/*-FAT-debug*" />
278             </fileset>
279         </reflexive>
280
281         <!-- original jsb2 builds -->
282         <!-- NOTE as jsb2tk has no path adoption yet we need to do it here -->
283         <copy toDir="${project.basedir}">
284             <fileset dir="${builddir}">
285                 <include name="${name}/*/*" />
286             </fileset>
287
288             <filterchain>
289                 <replaceregexp>
290                     <regexp pattern="(\.\.\/){2,}images" replace="../../images" modifiers="i"/>
291                     <regexp pattern="(\.\.\/){2,}library" replace="../../library" modifiers="i"/>
292                 </replaceregexp>
293             </filterchain>
294
295         </copy>
296
297         <!-- adopt path for getJS/getCSS -->
298         <!-- TODO add deploymode GETTER and move this to jsb2tk -->
299         <copy toDir="${project.basedir}">
300             <mapper type="regexp" from="^(.*\.(js|css))" to="\1.inc"/>
301
302             <filterchain>
303                 <replaceregexp>
304                     <regexp pattern="(\.\.\/)+images" replace="images" modifiers="i"/>
305                     <regexp pattern="(\.\.\/)+library" replace="library" modifiers="i"/>
306                 </replaceregexp>
307             </filterchain>
308
309             <fileset dir="${builddir}">
310                 <include name="${name}/*/*" />
311             </fileset>
312
313         </copy>
314
315         <!-- translations -->
316         <if>
317             <available file="${builddir}/${name}/js" type="dir" property="has_jsdir"/>
318             <then>
319                 <echo message="Building translations..." />
320                 <translation-build appName="${name}" />
321                 <jsMin targetDir="${builddir}/${name}/js" failOnError="false">
322                     <fileset dir="${builddir}/${name}/js">
323                         <include name="*-lang-*-debug.js"/>
324                     </fileset>
325                 </jsMin>
326
327                 <copy toDir="${project.basedir}/${name}/js">
328                     <fileset dir="${builddir}/${name}/js">
329                         <include name="*-lang-*-debug.js" />
330                     </fileset>
331                 </copy>
332
333                 <copy toDir="${project.basedir}/${name}/js">
334                     <fileset dir="${builddir}/${name}/js">
335                         <include name="*-lang-*-debug-min.js" />
336                     </fileset>
337
338                     <mapper type="regexp" from="^(.*)-debug-min.js" to="\1.js"/>
339                 </copy>
340             </then>
341         </if>
342     </target>
343
344     <!-- ============================================  -->
345     <!-- Target: clean                                 -->
346     <!-- ============================================  -->
347     <target name="clean">
348         <delete dir="${builddir}" includeemptydirs="true" verbose="false" failonerror="false" />
349         <delete dir="${userdatadir}" includeemptydirs="true" verbose="false" failonerror="false" />
350         <delete>
351             <fileset dir=".">
352                 <include name="*/*/*-FAT*" />
353                 <include name="*/js/*-lang-*" />
354                 <include name="${project.basedir}/${localedir}/build/*" />
355             </fileset>
356         </delete>
357     </target>
358
359     <!-- ============================================  -->
360     <!-- Target: mimetypes                                 -->
361     <!-- ============================================  -->
362     <target name="mimetypes">
363         <build-mimetypes appName="${name}" />
364     </target>
365
366     <!-- ============================================  -->
367     <!-- Target: tx-pull                               -->
368     <!-- ============================================  -->
369     <target name="tx-pull">
370         <echo msg="pull translations from transifex" />
371         <exec command="tx pull -a -f --skip" passthru="true" />
372         <echo msg="Commit updated strings now:" />
373         <echo msg="$ git add */translations" />
374         <echo msg="$ git commit -m '#7086: update translation files'" />
375         <echo msg="$ git push gerrit HEAD:refs/heads/master" />
376         <echo msg="You might run the target translation-test now:" />
377         <echo msg="$ ./vendor/bin/phing translation-test" />
378     </target>
379
380     <!-- ============================================  -->
381     <!-- Target: tx-push                               -->
382     <!-- ============================================  -->
383     <target name="tx-push">
384         <echo msg="updating templates" />
385         <exec command="./langHelper.php --pot" passthru="true" />
386         <echo msg="push translations to transifex" />
387         <exec command="tx push -s" passthru="true" />
388         <echo msg="commit updated strings now:" />
389         <echo msg="git commit -a -m 'update lang templates'" />
390         <echo msg="git push gerrit HEAD:refs/heads/master" />
391     </target>
392
393     <!-- ============================================  -->
394     <!-- Target: translation-test                      -->
395     <!-- ============================================  -->
396     <target name="translation-test">
397         <echo msg="find duplicates or syntax errors" />
398         <exec command="for i in `ls ./*/translations/*.po`; do msgfmt -o - --strict $i 1>/dev/null; done" passthru="true"/>
399     </target>
400     
401     <!-- ============================================  -->
402     <!-- Target: tine-install                               -->
403     <!-- ============================================  -->
404     <target name="tine-install">
405         <property file="${configdir}/install.properties" />
406         <echo msg="Installing Tine 2.0 with initial admin '${adminLoginName}'" />
407         <exec command="php -d include_path=.:${configdir} setup.php \
408             --install -- \
409                 adminLoginName=${adminLoginName} \
410                 adminPassword=${adminPassword} \
411                 adminEmailAddress=${adminEmailAddress} \
412                 acceptedTermsVersion=1000 \
413                 imap=${imap} \
414                 smtp=${smtp} \
415                 authentication=${authentication} \
416                 accounts=${accounts} \
417                 sieve=${sieve}
418 " passthru="true" returnProperty="return"/>
419         <if>
420         <equals arg1="${return}" arg2="0" />
421         <then>
422             <echo message="Installation successful" />
423         </then>
424         <else>
425             <fail message="Installation failed" />
426         </else>
427         </if>
428     </target>
429
430     <!-- ============================================  -->
431     <!-- Target: tine-uninstall                               -->
432     <!-- ============================================  -->
433     <target name="tine-uninstall">
434         <echo msg="Uninstalling Tine 2.0" />
435         <exec command="php -d include_path=.:${configdir} setup.php \
436             --uninstall" passthru="true"/>
437     </target>
438     
439     <!-- ============================================  -->
440     <!-- Task: init                                    -->
441     <!-- ============================================  -->
442     <adhoc-task name="init"><![CDATA[
443         class initTask extends Task {
444             function main() {
445                 passthru('composer install --prefer-source --no-interaction');
446                 require_once 'vendor/autoload.php';
447             }
448         }
449     ]]></adhoc-task>
450
451     <!-- ============================================  -->
452     <!-- Task: jsb2tk-build                            -->
453     <!-- ============================================  -->
454     <adhoc-task name="jsb2tk-build"><![CDATA[
455         class jsb2tkTask extends Task {
456             private $appName;
457
458             function setAppName($appName) {
459                 $this->appName = $appName;
460             }
461
462             function main() {
463                 $jsb2 = "${project.basedir}/{$this->appName}/{$this->appName}.jsb2";
464                 if (file_exists($jsb2)) {
465                     $this->log("In jsb2tkTask: " . $this->appName);
466
467                     require_once('${project.basedir}/library/jsb2tk/jsb2tk.php');
468
469                     $tk = new jsb2tk(array(
470                         'homeDir' => '${builddir}'
471                     ));
472
473                     $tk->register($jsb2);
474                     $tk->buildAll();
475                 }
476             }
477         }
478     ]]></adhoc-task>
479
480     <!-- ============================================  -->
481     <!-- Task: translation-build                       -->
482     <!-- ============================================  -->
483     <adhoc-task name="translation-build"><![CDATA[
484         class translationTask extends Task {
485             private $appName;
486
487             function setAppName($appName) {
488                 $this->appName = $appName;
489             }
490
491             function main() {
492                 if (! file_exists('${builddir}/' . "{$this->appName}/js")) return;
493                 $availableTranslations = Tinebase_Translation::getAvailableTranslations();
494
495                 foreach ($availableTranslations as $translation) {
496                     $localeString = $translation['locale'];
497                     $locale = new Zend_Locale($localeString);
498
499                     $jsTranslation = Tinebase_Translation::getJsTranslations($locale, $this->appName);
500
501                     if ($this->appName == 'Tinebase' && file_exists('${project.basedir}/langstatistics.json')) {
502                         $langstatistics = json_decode(file_get_contents('${project.basedir}/langstatistics.json'), TRUE);
503                         $localeStats = array_values(array_filter($langstatistics['langStats'], function($stats) use ($localeString) {return $stats['locale'] == $localeString;}));
504                         $jsTranslation .= ("Locale.translationStats=" . json_encode($localeStats[0]) . ";\n");
505                     }
506
507                     file_put_contents('${builddir}/' . "{$this->appName}/js/{$this->appName}-lang-{$locale}-debug.js", $jsTranslation);
508                 }
509
510                 foreach (Tinebase_Translation::getTranslationDirs() as $appName => $translationPath) {
511                     foreach (scandir($translationPath) as $poFile) {
512                         if (substr($poFile, -3) == '.po') {
513                             $langName = substr($poFile, 0, -3);
514                             `cd "$translationPath"
515                             msgfmt -o $langName.mo $poFile`;
516                         }
517                     }
518                 }
519             }
520         }
521     ]]></adhoc-task>
522
523     <!-- ============================================  -->
524     <!-- Task: build-mimetypes                         -->
525     <!-- ============================================  -->
526     <adhoc-task name="build-mimetypes"><![CDATA[
527         class mimetypeTask extends Task {
528             private $appName;
529
530             function setAppName($appName) {
531                 $this->appName = $appName;
532             }
533
534             function buildMimeTypesStyleFile($resolution, &$styleSheet) {
535
536                 $relatedImgPath = '/images/oxygen/'.$resolution.'/mimetypes/';
537                 $imgPath = '${project.basedir}'.$relatedImgPath;
538                 if (! file_exists($imgPath) || ! is_dir($imgPath)) {
539                     echo 'Mimetype images no found!';
540                     return;
541                 }
542
543                 // √∂ffnen des Verzeichnisses
544                 if ( $handle = opendir($imgPath) ) {
545
546                     fwrite($styleSheet, ".standardFileClass_".$resolution." .x-grid3-cell-inner {\n");
547                     fwrite($styleSheet, "    background-image: url(../..".$relatedImgPath."application-octet-stream.png);\n");
548                     fwrite($styleSheet, "    background-repeat:  no-repeat;\n");
549                     fwrite($styleSheet, "    padding-left: 19px;\n");
550                     fwrite($styleSheet, "}\n\n");
551
552                     // einlesen der Verzeichnisses
553                     while (($file = readdir($handle)) !== false)
554                     {
555                         $fileName = basename($file, '.png');
556
557                         $addToStyle = strcmp($fileName, "..") + strcmp($fileName, "..");
558                         if($addToStyle > 0) {
559
560                             fwrite($styleSheet, ".".$fileName."_".$resolution." .x-grid3-cell-inner {\n");
561                             fwrite($styleSheet, "    background-image: url(../..".$relatedImgPath.$file.") !important;\n");
562                             fwrite($styleSheet, "    background-repeat:  no-repeat;\n");
563                             fwrite($styleSheet, "    padding-left: 19px;\n");
564                             fwrite($styleSheet, "}\n\n");
565                         }
566                     }
567
568                     closedir($handle);
569                 }
570             }
571
572             function main() {
573                     $styleSheet = fopen('Tinebase/css/mimetypes.css', 'w+');
574                     $this->buildMimeTypesStyleFile('16x16', $styleSheet);
575                     $this->buildMimeTypesStyleFile('22x22', $styleSheet);
576                     $this->buildMimeTypesStyleFile('32x32', $styleSheet);
577                     fclose($styleSheet);
578             }
579         }
580     ]]></adhoc-task>
581
582
583     <!-- ============================================  -->
584     <!-- Task: manifest-build                          -->
585     <!-- TODO  make it working (just a codestore)      -->
586     <!-- ============================================  -->
587     <adhoc-task name="manifest-build"><![CDATA[
588         class manifestBuildTask extends Task {
589             private $appName;
590
591             function setAppName($appName) {
592                 $this->appName = $appName;
593             }
594
595             function main() {
596                 $defaultFiles = "CACHE MANIFEST\n# Build by $build\nCACHE:\n";
597
598                 $manifest = fopen('${project.basedir}/tine20.manifest', 'w+');
599                 fwrite($manifest, $defaultFiles . "\n");
600
601                 $files = array(
602                     'Tinebase/css/tine-all.css',
603                     'Tinebase/js/tine-all.js',
604                     'styles/tine20.css', 
605                     'library/ExtJS/ext-all.js',
606                     'library/ExtJS/adapter/ext/ext-base.js',
607                     'library/ExtJS/resources/css/ext-all.css',
608                     'images/oxygen/16x16/actions/knewstuff.png' // ???
609                 );
610
611                 // no subdirs! => solaris does not know find -maxdeps 1
612                 exec("cd \"$tine20path\"; ls images/* | grep images/ | egrep '\.png|\.gif|\.jpg'", $baseImages);
613                 $files = array_merge($files, $baseImages);
614
615                 $tineCSS = file_get_contents($tine20path . '/Tinebase/css/tine-all-debug.css');
616                 preg_match_all('/url\(..\/..\/(images.*)\)/U', $tineCSS, $matches);
617                 $files = array_merge($files, $matches[1]);
618
619                 $tineCSS = file_get_contents($tine20path . '/Tinebase/css/tine-all-debug.css');
620                 preg_match_all('/url\(..\/..\/(library.*)\)/U', $tineCSS, $matches);
621                 $files = array_merge($files, $matches[1]);
622
623                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
624                 preg_match_all('/labelIcon: [\'|"](.*png)/U', $tineJs, $matches);
625                 $files = array_merge($files, $matches[1]);
626
627                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
628                 preg_match_all('/labelIcon: [\'|"](.*gif)/U', $tineJs, $matches);
629                 $files = array_merge($files, $matches[1]);
630
631                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
632                 preg_match_all('/src=[\'|"](.*png)/U', $tineJs, $matches);
633                 $files = array_merge($files, $matches[1]);
634
635                 $tineJs = file_get_contents($tine20path . '/Tinebase/js/tine-all-debug.js');
636                 preg_match_all('/src=[\'|"](.*gif)/U', $tineJs, $matches);
637                 $files = array_merge($files, $matches[1]);
638
639                 exec("cd \"$tine20path\"; find library/ExtJS/resources/images -type f -name *.gif", $extImages);
640                 $files = array_merge($files, $extImages);
641                 exec("cd \"$tine20path\"; find library/ExtJS/resources/images -type f -name *.png", $extImages);
642                 $files = array_merge($files, $extImages);
643
644                 exec("cd \"$tine20path\"; find styles -type f", $tine20Styles);
645                 $files = array_merge($files, $tine20Styles);
646
647                 $files = array_unique($files);
648
649                 foreach($files as $file) {
650                     if (! is_file("$tine20path/$file")) {
651                         echo "WARNING $file not found, removing it from manifest.\n";
652                     } else if (substr(basename($file), 0, 1) == '.' || ! preg_match('/(js|css|gif|png|jpg)$/', $file))  {
653                         echo "INFO $file is unwanted, removing it from manifest.\n";
654                     } else {
655                         fwrite($manifest, $file . "\n");
656                     }
657                 }
658
659                 fclose($manifest);
660             }
661         }
662     ]]></adhoc-task>
663
664     <!-- ============================================  -->
665     <!-- Task: zend-translation-build                  -->
666     <!-- TODO  make a target for this                  -->
667     <!-- ============================================  -->
668     <adhoc-task name="zend-translation-build"><![CDATA[
669         class zendTranslationTask extends Task {
670             function main() {
671                 // dump one langfile for every locale
672                 $localelist = Zend_Locale::getLocaleList();
673                 foreach ($localelist as $locale => $something) {
674                     try {
675                         $js = $this->createJsTranslationLists($locale);
676                         file_put_contents('${builddir}/${localedir}/static/' . "generic-$locale-debug.js", $js);
677                     } catch (Exception $e) {
678                         echo "WARNING: could not create translation file for '$locale': '{$e->getMessage()}'\n";
679                     }
680                 }
681             }
682
683             /**
684              * creates translation lists js files for locale with js object
685              *
686              * @param   string $_locale
687              * @return  string the file contents
688              */
689             function createJsTranslationLists($_locale) {
690                 $jsContent = "Locale.prototype.TranslationLists = {\n";
691
692                 $types = array(
693                     'Date'           => array('path' => 'Date'),
694                     'Time'           => array('path' => 'Time'),
695                     'DateTime'       => array('path' => 'DateTime'),
696                     'Month'          => array('path' => 'Month'),
697                     'Day'            => array('path' => 'Day'),
698                     'Symbols'        => array('path' => 'Symbols'),
699                     'Question'       => array('path' => 'Question'),
700                     'Language'       => array('path' => 'Language'),
701                     'CountryList'    => array('path' => 'Territory', 'value' => 2),
702                     'Territory'      => array('path' => 'Territory', 'value' => 1),
703                     'CityToTimezone' => array('path' => 'CityToTimezone'),
704                 );
705
706                 $zendLocale = new Zend_Locale($_locale);
707
708                 foreach ( $types as $name => $path) {
709                     $list = $zendLocale->getTranslationList($path['path'], $_locale, array_key_exists('value', $path) ? $path['value'] : false);
710                     //print_r ( $list );
711
712                     if ( is_array($list) ) {
713                         $jsContent .= "\n\t$name: {";
714
715                         foreach ( $list as $key => $value ) {
716                             // convert ISO -> PHP for date formats
717                             if ( in_array($name, array('Date', 'Time', 'DateTime')) ) {
718                                 $value = $this->convertIsoToPhpFormat($value);
719                             }
720                             $value = preg_replace("/\"/", '\"', $value);
721                             $jsContent .= "\n\t\t'$key': \"$value\",";
722                         }
723                         // remove last comma
724                         $jsContent = chop($jsContent, ",");
725
726                         $jsContent .= "\n\t},";
727                     }
728                 }
729                 $jsContent = chop($jsContent, ",");
730
731                 $jsContent .= "\n};\n";
732                 return $jsContent;
733             }
734
735             /**
736              * Converts a format string from ISO to PHP format
737              * reverse the functionality of Zend's convertPhpToIsoFormat()
738              *
739              * @param  string  $format  Format string in PHP's date format
740              * @return string           Format string in ISO format
741              */
742             function convertIsoToPhpFormat($format) {
743                 $convert = array(
744                     'c' => '/yyyy-MM-ddTHH:mm:ssZZZZ/',
745                     '$1j$2' => '/([^d])d([^d])/',
746                     'j$1' => '/^d([^d])/',
747                     '$1j' => '/([^d])d$/',
748                     't' => '/ddd/',
749                     'd' => '/dd/',
750                     'l' => '/EEEE/',
751                     'D' => '/EEE/',
752                     'S' => '/SS/',
753                     'w' => '/eee/',
754                     'N' => '/e/',
755                     'z' => '/D/',
756                     'W' => '/w/',
757                     '$1n$2' => '/([^M])M([^M])/',
758                     'n$1' => '/^M([^M])/',
759                     '$1n' => '/([^M])M$/',
760                     'F' => '/MMMM/',
761                     'M' => '/MMM/',
762                     'm' => '/MM/',
763                     'L' => '/l/',
764                     'o' => '/YYYY/',
765                     'Y' => '/yyyy/',
766                     'y' => '/yy/',
767                     'a' => '/a/',
768                     'A' => '/a/',
769                     'B' => '/B/',
770                     'h' => '/hh/',
771                     'g' => '/h/',
772                     '$1G$2' => '/([^H])H([^H])/',
773                     'G$1' => '/^H([^H])/',
774                     '$1G' => '/([^H])H$/',
775                     'H' => '/HH/',
776                     'i' => '/mm/',
777                     's' => '/ss/',
778                     'e' => '/zzzz/',
779                     'I' => '/I/',
780                     'P' => '/ZZZZ/',
781                     'O' => '/Z/',
782                     'T' => '/z/',
783                     'Z' => '/X/',
784                     'r' => '/r/',
785                     'U' => '/U/',
786                 );
787
788                 //echo "pre:".$format."\n";
789
790                 $patterns = array_values($convert);
791                 $replacements = array_keys($convert);
792                 $format = preg_replace($patterns, $replacements, $format);
793
794                 //echo "post:".$format."\n";
795                 //echo "---\n";
796
797                 return $format;
798             }
799         }
800     ]]></adhoc-task>
801 </project>