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