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